From 60cf44e6304e9a3608441fd8112ba2f37cac96b1 Mon Sep 17 00:00:00 2001 From: CheerfulUser Date: Thu, 13 Jun 2024 17:31:31 +1200 Subject: [PATCH] fixed errors --- development/test_statistics_range.ipynb | 14886 +++++++++++++++++++++- tessreduce/helpers.py | 36 +- tessreduce/tessreduce.py | 6 +- 3 files changed, 14857 insertions(+), 71 deletions(-) diff --git a/development/test_statistics_range.ipynb b/development/test_statistics_range.ipynb index ddbf811..d364255 100644 --- a/development/test_statistics_range.ipynb +++ b/development/test_statistics_range.ipynb @@ -2,26 +2,19 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, - "id": "6e1a09d3-2f93-4a23-ac33-716e9a43428d", + "execution_count": 98, + "id": "c5256788", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Matplotlib is building the font cache; this may take a moment.\n" - ] - } - ], + "outputs": [], "source": [ - "import tessreduce as tr" + "import tessreduce as tr\n", + "%matplotlib notebook" ] }, { "cell_type": "code", - "execution_count": 2, - "id": "796a8a0a-ddd7-48b7-9a57-744bd79a6557", + "execution_count": 485, + "id": "e83ddf8a", "metadata": {}, "outputs": [ { @@ -37,16 +30,1001 @@ "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" + "Background correlation correction\n" ] }, { "data": { - "image/png": "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", + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_device_pixel_ratio', {\n", + " device_pixel_ratio: fig.ratio,\n", + " });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute('tabindex', '0');\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;' +\n", + " 'z-index: 2;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'pointer-events: none;' +\n", + " 'position: relative;' +\n", + " 'z-index: 0;'\n", + " );\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'left: 0;' +\n", + " 'pointer-events: none;' +\n", + " 'position: absolute;' +\n", + " 'top: 0;' +\n", + " 'z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " /* This rescales the canvas back to display pixels, so that it\n", + " * appears correct on HiDPI screens. */\n", + " canvas.style.width = width + 'px';\n", + " canvas.style.height = height + 'px';\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " /* User Agent sniffing is bad, but WebKit is busted:\n", + " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", + " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", + " * The worst that happens here is that they get an extra browser\n", + " * selection when dragging, if this check fails to catch them.\n", + " */\n", + " var UA = navigator.userAgent;\n", + " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", + " if(isWebKit) {\n", + " return function (event) {\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We\n", + " * want to control all of the cursor setting manually through\n", + " * the 'cursor' event from matplotlib */\n", + " event.preventDefault()\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " } else {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'dblclick',\n", + " on_mouse_event_closure('dblclick')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " canvas_div.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " canvas_div.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " fig.canvas_div.style.cursor = msg['cursor'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " var img = evt.data;\n", + " if (img.type !== 'image/png') {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " img.type = 'image/png';\n", + " }\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " img\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "function getModifiers(event) {\n", + " var mods = [];\n", + " if (event.ctrlKey) {\n", + " mods.push('ctrl');\n", + " }\n", + " if (event.altKey) {\n", + " mods.push('alt');\n", + " }\n", + " if (event.shiftKey) {\n", + " mods.push('shift');\n", + " }\n", + " if (event.metaKey) {\n", + " mods.push('meta');\n", + " }\n", + " return mods;\n", + "}\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * https://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " // from https://stackoverflow.com/q/1114465\n", + " var boundingRect = this.canvas.getBoundingClientRect();\n", + " var x = (event.clientX - boundingRect.left) * this.ratio;\n", + " var y = (event.clientY - boundingRect.top) * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " modifiers: getModifiers(event),\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.key === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.key;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.key !== 'Control') {\n", + " value += 'ctrl+';\n", + " }\n", + " else if (event.altKey && event.key !== 'Alt') {\n", + " value += 'alt+';\n", + " }\n", + " else if (event.shiftKey && event.key !== 'Shift') {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k' + event.key;\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.binaryType = comm.kernel.ws.binaryType;\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " function updateReadyState(_event) {\n", + " if (comm.kernel.ws) {\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " } else {\n", + " ws.readyState = 3; // Closed state.\n", + " }\n", + " }\n", + " comm.kernel.ws.addEventListener('open', updateReadyState);\n", + " comm.kernel.ws.addEventListener('close', updateReadyState);\n", + " comm.kernel.ws.addEventListener('error', updateReadyState);\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " var data = msg['content']['data'];\n", + " if (data['blob'] !== undefined) {\n", + " data = {\n", + " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", + " };\n", + " }\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(data);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], "text/plain": [ - "
" + "" ] }, "metadata": {}, @@ -54,13 +1032,13 @@ } ], "source": [ - "tess = tr.tessreduce(tpf='../../../../data/tess/2020fqv.fits')#ra=ra,dec=dec,size=90)#,sector=sector)" + "tess = tr.tessreduce(tpf='../../../../data/tess/2020fqv.fits',calibrate=False,corr_correction=)#ra=ra,dec=dec,size=90)#,sector=sector)" ] }, { "cell_type": "code", "execution_count": 3, - "id": "00686129-1987-4e1a-beb6-4a5e719e7408", + "id": "6712f1e3", "metadata": {}, "outputs": [], "source": [ @@ -69,13 +1047,38 @@ " #isf2 = 1.0/(sf*sf) # Removed this factor since we don't want scaling\n", " (A,B) = arr.shape\n", " windows = view_as_windows(arr, (sf,sf), step = sf)\n", - " return windows.sum(3).sum(2)#*isf2" + " return windows.sum(3).sum(2)#*isf2\n", + "\n" ] }, { "cell_type": "code", - "execution_count": 8, - "id": "8bbdfbc3-b424-4544-9dd9-1b626521f704", + "execution_count": null, + "id": "abd20a12", + "metadata": {}, + "outputs": [], + "source": [ + "def regional_stats_mask(image,size=90,sigma=3,iters=10):\n", + " if size < 30:\n", + " print('!!! Region size is small !!!')\n", + " sx, sy = image.shape\n", + " X, Y = np.ogrid[0:sx, 0:sy]\n", + " regions = sy//size * (X//size) + Y//size\n", + " max_reg = np.max(regions)\n", + "\n", + " clip = np.zeros_like(image)\n", + " for i in range(max_reg+1):\n", + " rx,ry = np.where(regions == i)\n", + " m,me, s = sigma_clipped_stats(image[ry,rx],maxiters=iters)\n", + " cut_ind = np.where((image[rx,ry] >= me+sigma*s) | (image[rx,ry] <= me-sigma*s))\n", + " clip[rx[cut_ind],ry[cut_ind]] = 1\n", + " return clip" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "d4b74cf9", "metadata": {}, "outputs": [ { @@ -84,7 +1087,7 @@ "array([[342220.93233425]])" ] }, - "execution_count": 8, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -95,8 +1098,8 @@ }, { "cell_type": "code", - "execution_count": 54, - "id": "87199c8b-a755-40e8-b07e-0abb4c40edca", + "execution_count": 5, + "id": "6a0887ea", "metadata": {}, "outputs": [], "source": [ @@ -108,13 +1111,13 @@ }, { "cell_type": "code", - "execution_count": 49, - "id": "47e5fef5-aef0-43a3-9efd-e2dc7ada03de", + "execution_count": 507, + "id": "05318f55", "metadata": {}, "outputs": [], "source": [ "ar = tess.ref\n", - "fact = 30\n", + "fact = 40\n", "sx, sy = ar.shape\n", "X, Y = np.ogrid[0:sx, 0:sy]\n", "regions = sy//fact * (X//fact) + Y//fact" @@ -122,8 +1125,8 @@ }, { "cell_type": "code", - "execution_count": 50, - "id": "4ed7ee67-db70-4c00-b3df-a8dfb06295b7", + "execution_count": 508, + "id": "da84be3e", "metadata": {}, "outputs": [], "source": [ @@ -133,29 +1136,1016 @@ }, { "cell_type": "code", - "execution_count": 51, - "id": "68ccf2fc-d531-4631-bde6-1e8c15982bac", + "execution_count": 509, + "id": "92461221", "metadata": {}, "outputs": [ { "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_device_pixel_ratio', {\n", + " device_pixel_ratio: fig.ratio,\n", + " });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute('tabindex', '0');\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;' +\n", + " 'z-index: 2;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'pointer-events: none;' +\n", + " 'position: relative;' +\n", + " 'z-index: 0;'\n", + " );\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'left: 0;' +\n", + " 'pointer-events: none;' +\n", + " 'position: absolute;' +\n", + " 'top: 0;' +\n", + " 'z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " /* This rescales the canvas back to display pixels, so that it\n", + " * appears correct on HiDPI screens. */\n", + " canvas.style.width = width + 'px';\n", + " canvas.style.height = height + 'px';\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " /* User Agent sniffing is bad, but WebKit is busted:\n", + " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", + " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", + " * The worst that happens here is that they get an extra browser\n", + " * selection when dragging, if this check fails to catch them.\n", + " */\n", + " var UA = navigator.userAgent;\n", + " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", + " if(isWebKit) {\n", + " return function (event) {\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We\n", + " * want to control all of the cursor setting manually through\n", + " * the 'cursor' event from matplotlib */\n", + " event.preventDefault()\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " } else {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'dblclick',\n", + " on_mouse_event_closure('dblclick')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " canvas_div.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " canvas_div.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " fig.canvas_div.style.cursor = msg['cursor'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " var img = evt.data;\n", + " if (img.type !== 'image/png') {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " img.type = 'image/png';\n", + " }\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " img\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "function getModifiers(event) {\n", + " var mods = [];\n", + " if (event.ctrlKey) {\n", + " mods.push('ctrl');\n", + " }\n", + " if (event.altKey) {\n", + " mods.push('alt');\n", + " }\n", + " if (event.shiftKey) {\n", + " mods.push('shift');\n", + " }\n", + " if (event.metaKey) {\n", + " mods.push('meta');\n", + " }\n", + " return mods;\n", + "}\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * https://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " // from https://stackoverflow.com/q/1114465\n", + " var boundingRect = this.canvas.getBoundingClientRect();\n", + " var x = (event.clientX - boundingRect.left) * this.ratio;\n", + " var y = (event.clientY - boundingRect.top) * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " modifiers: getModifiers(event),\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.key === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.key;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.key !== 'Control') {\n", + " value += 'ctrl+';\n", + " }\n", + " else if (event.altKey && event.key !== 'Alt') {\n", + " value += 'alt+';\n", + " }\n", + " else if (event.shiftKey && event.key !== 'Shift') {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k' + event.key;\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.binaryType = comm.kernel.ws.binaryType;\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " function updateReadyState(_event) {\n", + " if (comm.kernel.ws) {\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " } else {\n", + " ws.readyState = 3; // Closed state.\n", + " }\n", + " }\n", + " comm.kernel.ws.addEventListener('open', updateReadyState);\n", + " comm.kernel.ws.addEventListener('close', updateReadyState);\n", + " comm.kernel.ws.addEventListener('error', updateReadyState);\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " var data = msg['content']['data'];\n", + " if (data['blob'] !== undefined) {\n", + " data = {\n", + " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", + " };\n", + " }\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(data);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], "text/plain": [ - "[]" + "" ] }, - "execution_count": 51, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAaAAAAGgCAYAAADsNrNZAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAAAzHklEQVR4nO3de3BT550+8Ed3G4xlbLBkgwUOl9hAyAUSY2C33cRdD2WysLjZpkO2TsI0m8SQgLdNcTeQZhtiNp0NlA6XTYaFdBLKhtmGlnRKfqmzpU1qbk5IQ9MYCBSbiwS5WDIGy5LO+/vDWNbRxVi2rPfIej4zmq1fHR1/fbbVwznf9z1HJ4QQICIiSjK97AKIiCg9MYCIiEgKBhAREUnBACIiIikYQEREJAUDiIiIpGAAERGRFAwgIiKSggFERERSMICIiEiKIQugzZs3Y+LEicjIyEBZWRkOHz48VL+KiIhSkG4o7gX3P//zP/j2t7+Nbdu2oaysDBs3bsSePXvQ3NyM/Pz8Pj+rKAouXLiAUaNGQafTJbo0IiIaYkIItLe3o7CwEHp9H+c5YgjcddddoqamJvhzIBAQhYWFor6+/oafbW1tFQD44osvvvhK8Vdra2uf3/dGJFhXVxeamppQV1cXHNPr9aioqEBjY2PE9l6vF16vN/izuH5CNh9fhxGmRJdHGmMonSK7BEqi9slW2SVQEgR8nWjavw6jRo3qc7uEB9Bnn32GQCAAm82mGrfZbPjkk08itq+vr8ezzz4bpTATjDoG0HBnMFhkl0BJZDRlyC6BkuhGbRTps+Dq6urgdruDr9bWVtklERFREiT8DGjMmDEwGAxwuVyqcZfLBbvdHrG9xWKBxcJ/BRMRpZuEnwGZzWbMmjULDQ0NwTFFUdDQ0IDy8vJE/zoiIkpRCT8DAoDa2lpUV1dj9uzZuOuuu7Bx40Z0dHTgoYceGopfR0REKWhIAuib3/wmLl++jLVr18LpdOK2227D/v37IyYmEBFR+hqSAAKA5cuXY/ny5UO1eyIiSnHSZ8EREVF6YgAREZEUDCAiIpKCAURERFIwgIiISAoGEBERScEAIiIiKRhAREQkBQOIiIikYAAREZEUDCAiIpKCAURERFIwgIiISAoGEBERScEAIiIiKRhAREQkBQOIiIikYAAREZEUDCAiIpKCAURERFIwgIiISAoGEBERScEAIiIiKRhAREQkBQOIiIikYAAREZEUDCAiIpKCAURERFIwgIiISAoGEBERSRF3AP3+97/Hvffei8LCQuh0Ouzdu1f1vhACa9euRUFBATIzM1FRUYGTJ08mql4iIhom4g6gjo4O3Hrrrdi8eXPU91944QVs2rQJ27Ztw6FDhzBy5EhUVlais7Nz0MUSEdHwYYz3AwsWLMCCBQuivieEwMaNG/H0009j0aJFAICf/exnsNls2Lt3L+6///7BVUtERMNGQntAZ86cgdPpREVFRXDMarWirKwMjY2NUT/j9Xrh8XhULyIiGv4SGkBOpxMAYLPZVOM2my34Xrj6+npYrdbgq6ioKJElERGRRkmfBVdXVwe32x18tba2yi6JiIiSIKEBZLfbAQAul0s17nK5gu+Fs1gsyM7OVr2IiGj4S2gAFRcXw263o6GhITjm8Xhw6NAhlJeXJ/JXERFRiot7FtyVK1dw6tSp4M9nzpzBsWPHkJubC4fDgZUrV+K5557DlClTUFxcjDVr1qCwsBCLFy9OZN1ERJTi4g6go0eP4u/+7u+CP9fW1gIAqqursXPnTjz11FPo6OjAI488gra2NsyfPx/79+9HRkZG4qomIqKUpxNCCNlFhPJ4PLBarfgqFsGoM8kuh4aYYfrNskugJGqfmiO7BEoCv68Th/etgdvt7rOvL30WHBERpScGEBERScEAIiIiKRhAREQkBQOIiIikYAAREZEUDCAiIpKCAURERFIwgIiISAoGEBERScEAIiIiKRhAREQkBQOIiIikYAAREZEUDCAiIpKCAURERFIwgIiISAoGEBERScEAIiIiKRhAREQkBQOIiIikYAAREZEUDCAiIpKCAURERFIwgIiISAoGEBERScEAIiIiKRhAREQkBQOIiIikYAAREZEUcQVQfX097rzzTowaNQr5+flYvHgxmpubVdt0dnaipqYGeXl5yMrKQlVVFVwuV0KLJiKi1BdXAB04cAA1NTU4ePAg3n77bfh8Pvz93/89Ojo6gtusWrUK+/btw549e3DgwAFcuHABS5YsSXjhRESU2ozxbLx//37Vzzt37kR+fj6amprwt3/7t3C73di+fTt27dqFu+++GwCwY8cOlJaW4uDBg5gzZ07iKiciopQ2qB6Q2+0GAOTm5gIAmpqa4PP5UFFREdympKQEDocDjY2NUffh9Xrh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", + "text/html": [ + "" + ], "text/plain": [ - "
" + "" ] }, "metadata": {}, "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 509, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -167,7 +2157,7 @@ { "cell_type": "code", "execution_count": 52, - "id": "2b72ba9a-4855-4c1d-aaf4-b76f4f344707", + "id": "adc868c2", "metadata": {}, "outputs": [], "source": [] @@ -175,7 +2165,7 @@ { "cell_type": "code", "execution_count": 64, - "id": "fa5971df-fe14-4116-8185-a888798b9818", + "id": "733da202", "metadata": {}, "outputs": [ { @@ -195,41 +2185,12813 @@ }, { "cell_type": "code", - "execution_count": 91, - "id": "342802ea-d625-4895-b3a6-5d6332c0fe80", + "execution_count": 35, + "id": "9b450598", + "metadata": {}, + "outputs": [], + "source": [ + "image = tess.ref\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "f3b5d9e0", "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n", - "2\n", - "2\n" - ] + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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hILBoL75zW8qGAzaDsXXaEd30I7uoB3dkS/t6LkLEwAAhcPTPSEAQH4jCQEArCEJAQCsIQkBAKwhCQEArPFsEnr++edVUVGh6dOna+HChXrrrbdsh+RpTU1NuvvuuxUKhTRz5kw9+OCDOnXqVMY2xhg1NjYqFoupuLhYNTU16urqshSxPzQ1NSkQCKiuri69jHYcn1/96ld69NFHdfPNN6ukpER33nmnTpw4kV5PO47twoUL+sY3vqGKigoVFxdrzpw5evrppzU8/H83UfV9OxoPOnTokJk6darZu3evOXnypNmwYYOZMWOGOXPmjO3QPOuzn/2s2bdvn/mP//gP09HRYZYvX25mzZplPvzww/Q2O3bsMKFQyLz00kums7PTfOELXzBlZWUmlUpZjNy73n77bXPbbbeZO+64w2zYsCG9nHYc2//8z/+Y2bNnm8cff9z8+7//u+nu7jZvvPGG+cUvfpHehnYc27Zt28zNN99s/umf/sl0d3ebf/iHfzA33nijaW5uTm/j93b0ZBL61Kc+ZdatW5exbO7cuWbz5s2WIvKf3t5eI8m0tbUZY4wZHh420WjU7NixI73N//7v/5pwOGy+9a1v2QrTswYGBkw8Hjetra2muro6nYRox/HZtGmTWbJkyTXX047js3z5cvPEE09kLFu5cqV59NFHjTH50Y6eG44bGhrSiRMnVFtbm7G8trZW7e3tlqLyn/7+fknSTTfdJEnq7u5WMpnMaNdgMKjq6mradRRPPvmkli9frvvuuy9jOe04Pq+++qoWLVqkhx56SDNnztRdd92lvXv3ptfTjuOzZMkS/eAHP9Dp06clST/72c907Ngx3X///ZLyox09dxftDz74QBcvXlQkEslYHolElEwmLUXlL8YY1dfXa8mSJZo/f74kpdtutHY9c+bMpMfoZYcOHdJPfvITHT9+fMQ62nF83n33Xe3evVv19fX6+te/rrfffltf+cpXFAwG9cUvfpF2HKdNmzapv79fc+fO1ZQpU3Tx4kVt375dq1atkpQf56PnktBllx/jcJkxZsQyjO6pp57Sz3/+cx07dmzEOtr1+np6erRhwwYdOXJE06dPv+Z2tOP1DQ8Pa9GiRUokEpKku+66S11dXdq9e7e++MUvprejHa/vxRdf1MGDB9XS0qJ58+apo6NDdXV1isViWrNmTXo7P7ej54bjbrnlFk2ZMmVEr6e3t3dEtsdIX/7yl/Xqq6/qX/7lXzKeaBiNRiWJdh3DiRMn1Nvbq4ULF6qoqEhFRUVqa2vT3/7t36qoqCjdVrTj9ZWVlen222/PWPaJT3xC7733niTOx/H62te+ps2bN+vhhx/WggUL9Nhjj+mrX/2qmpqaJOVHO3ouCU2bNk0LFy5Ua2trxvLW1lZVVVVZisr7jDF66qmndPjwYf3whz9URUVFxvqKigpFo9GMdh0aGlJbWxvteoXPfOYz6uzsVEdHR/q1aNEiPfLII+ro6NCcOXNox3G49957R0wROH36tGbPni2J83G8zp07N+LJpFOmTElfop0X7WjxoohrunyJ9re//W1z8uRJU1dXZ2bMmGH+67/+y3ZonvXnf/7nJhwOm6NHj5qzZ8+mX+fOnUtvs2PHDhMOh83hw4dNZ2enWbVqla8u5bTlyqvjjKEdx+Ptt982RUVFZvv27eadd94xf/d3f2dKSkrMwYMH09vQjmNbs2aN+d3f/d30JdqHDx82t9xyi9m4cWN6G7+3oyeTkDHGPPfcc2b27Nlm2rRp5pOf/GT6UmOMTtKor3379qW3GR4eNt/85jdNNBo1wWDQfPrTnzadnZ32gvaJq5MQ7Tg+//iP/2jmz59vgsGgmTt3rtmzZ0/GetpxbKlUymzYsMHMmjXLTJ8+3cyZM8ds2bLFDA4OprfxezvyPCEAgDWeqwkBAAoHSQgAYA1JCABgDUkIAGANSQgAYA1JCABgDUkIAGANSQgAYA1JCABgDUkIAGANSQgAYM3/A2TJBpcAeNF7AAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ - "ar = tess.ref\n", - "fact = 80\n", - "sx, sy = ar.shape\n", + "plt.figure()\n", + "plt.imshow(regional_stats_mask(tess.ref,90))" + ] + }, + { + "cell_type": "code", + "execution_count": 231, + "id": "e83d280b", + "metadata": {}, + "outputs": [], + "source": [ + "flux = tess.bkg\n", + "size = 90\n", + "sx, sy = flux[0].shape\n", "X, Y = np.ogrid[0:sx, 0:sy]\n", - "regions = sy//fact * (X//fact) + Y//fact\n", + "regions = sy//size * (X//size) + Y//size\n", "max_reg = np.max(regions)\n", "\n", - "clip = np.zeros_like(ar)\n", + "clip = np.zeros_like(flux)\n", "for i in range(max_reg+1):\n", - " print(max_reg)\n", " rx,ry = np.where(regions == i)\n", - " m,me, s = sigma_clipped_stats(ar[ry,rx],maxiters=10)\n", - " cut_ind = np.where((ar[rx,ry] >= me+2*s) | (ar[rx,ry] <= me-2*s))\n", - " clip[rx[cut_ind],ry[cut_ind]] = 1\n" + " m,me, s = sigma_clipped_stats(flux[:,ry,rx],maxiters=10,axis=(1))\n", + " cut_ind = np.where((flux[:,rx,ry] >= (me+2*s)[:,np.newaxis]) | \n", + " (flux[:,rx,ry] <= (me-2*s)[:,np.newaxis]))\n", + " clip[cut_ind[0],rx[cut_ind[1]],ry[cut_ind[1]]] = 1\n" + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "id": "21d00d94", + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_device_pixel_ratio', {\n", + " device_pixel_ratio: fig.ratio,\n", + " });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute('tabindex', '0');\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;' +\n", + " 'z-index: 2;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'pointer-events: none;' +\n", + " 'position: relative;' +\n", + " 'z-index: 0;'\n", + " );\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'left: 0;' +\n", + " 'pointer-events: none;' +\n", + " 'position: absolute;' +\n", + " 'top: 0;' +\n", + " 'z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " /* This rescales the canvas back to display pixels, so that it\n", + " * appears correct on HiDPI screens. */\n", + " canvas.style.width = width + 'px';\n", + " canvas.style.height = height + 'px';\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " /* User Agent sniffing is bad, but WebKit is busted:\n", + " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", + " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", + " * The worst that happens here is that they get an extra browser\n", + " * selection when dragging, if this check fails to catch them.\n", + " */\n", + " var UA = navigator.userAgent;\n", + " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", + " if(isWebKit) {\n", + " return function (event) {\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We\n", + " * want to control all of the cursor setting manually through\n", + " * the 'cursor' event from matplotlib */\n", + " event.preventDefault()\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " } else {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'dblclick',\n", + " on_mouse_event_closure('dblclick')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " canvas_div.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " canvas_div.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " fig.canvas_div.style.cursor = msg['cursor'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " var img = evt.data;\n", + " if (img.type !== 'image/png') {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " img.type = 'image/png';\n", + " }\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " img\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "function getModifiers(event) {\n", + " var mods = [];\n", + " if (event.ctrlKey) {\n", + " mods.push('ctrl');\n", + " }\n", + " if (event.altKey) {\n", + " mods.push('alt');\n", + " }\n", + " if (event.shiftKey) {\n", + " mods.push('shift');\n", + " }\n", + " if (event.metaKey) {\n", + " mods.push('meta');\n", + " }\n", + " return mods;\n", + "}\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * https://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " // from https://stackoverflow.com/q/1114465\n", + " var boundingRect = this.canvas.getBoundingClientRect();\n", + " var x = (event.clientX - boundingRect.left) * this.ratio;\n", + " var y = (event.clientY - boundingRect.top) * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " modifiers: getModifiers(event),\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.key === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.key;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.key !== 'Control') {\n", + " value += 'ctrl+';\n", + " }\n", + " else if (event.altKey && event.key !== 'Alt') {\n", + " value += 'alt+';\n", + " }\n", + " else if (event.shiftKey && event.key !== 'Shift') {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k' + event.key;\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.binaryType = comm.kernel.ws.binaryType;\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " function updateReadyState(_event) {\n", + " if (comm.kernel.ws) {\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " } else {\n", + " ws.readyState = 3; // Closed state.\n", + " }\n", + " }\n", + " comm.kernel.ws.addEventListener('open', updateReadyState);\n", + " comm.kernel.ws.addEventListener('close', updateReadyState);\n", + " comm.kernel.ws.addEventListener('error', updateReadyState);\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " var data = msg['content']['data'];\n", + " if (data['blob'] !== undefined) {\n", + " data = {\n", + " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", + " };\n", + " }\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(data);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_device_pixel_ratio', {\n", + " device_pixel_ratio: fig.ratio,\n", + " });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute('tabindex', '0');\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;' +\n", + " 'z-index: 2;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'pointer-events: none;' +\n", + " 'position: relative;' +\n", + " 'z-index: 0;'\n", + " );\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'left: 0;' +\n", + " 'pointer-events: none;' +\n", + " 'position: absolute;' +\n", + " 'top: 0;' +\n", + " 'z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " /* This rescales the canvas back to display pixels, so that it\n", + " * appears correct on HiDPI screens. */\n", + " canvas.style.width = width + 'px';\n", + " canvas.style.height = height + 'px';\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " /* User Agent sniffing is bad, but WebKit is busted:\n", + " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", + " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", + " * The worst that happens here is that they get an extra browser\n", + " * selection when dragging, if this check fails to catch them.\n", + " */\n", + " var UA = navigator.userAgent;\n", + " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", + " if(isWebKit) {\n", + " return function (event) {\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We\n", + " * want to control all of the cursor setting manually through\n", + " * the 'cursor' event from matplotlib */\n", + " event.preventDefault()\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " } else {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'dblclick',\n", + " on_mouse_event_closure('dblclick')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " canvas_div.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " canvas_div.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " fig.canvas_div.style.cursor = msg['cursor'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " var img = evt.data;\n", + " if (img.type !== 'image/png') {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " img.type = 'image/png';\n", + " }\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " img\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "function getModifiers(event) {\n", + " var mods = [];\n", + " if (event.ctrlKey) {\n", + " mods.push('ctrl');\n", + " }\n", + " if (event.altKey) {\n", + " mods.push('alt');\n", + " }\n", + " if (event.shiftKey) {\n", + " mods.push('shift');\n", + " }\n", + " if (event.metaKey) {\n", + " mods.push('meta');\n", + " }\n", + " return mods;\n", + "}\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * https://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " // from https://stackoverflow.com/q/1114465\n", + " var boundingRect = this.canvas.getBoundingClientRect();\n", + " var x = (event.clientX - boundingRect.left) * this.ratio;\n", + " var y = (event.clientY - boundingRect.top) * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " modifiers: getModifiers(event),\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.key === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.key;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.key !== 'Control') {\n", + " value += 'ctrl+';\n", + " }\n", + " else if (event.altKey && event.key !== 'Alt') {\n", + " value += 'alt+';\n", + " }\n", + " else if (event.shiftKey && event.key !== 'Shift') {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k' + event.key;\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.binaryType = comm.kernel.ws.binaryType;\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " function updateReadyState(_event) {\n", + " if (comm.kernel.ws) {\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " } else {\n", + " ws.readyState = 3; // Closed state.\n", + " }\n", + " }\n", + " comm.kernel.ws.addEventListener('open', updateReadyState);\n", + " comm.kernel.ws.addEventListener('close', updateReadyState);\n", + " comm.kernel.ws.addEventListener('error', updateReadyState);\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " var data = msg['content']['data'];\n", + " if (data['blob'] !== undefined) {\n", + " data = {\n", + " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", + " };\n", + " }\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(data);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 105, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "i = 200\n", + "plt.figure()\n", + "plt.imshow(clip[i])\n", + "\n", + "plt.figure()\n", + "plt.imshow(flux[i])" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "id": "b0fa53d2", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline " + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "id": "85bdc970", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n", + " 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,\n", + " 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,\n", + " 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,\n", + " 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,\n", + " 85, 86, 87, 88, 89])" + ] + }, + "execution_count": 89, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def function(data, a, b, c):\n", + " x = data[0]\n", + " y = data[1]\n", + " return a * (x**b) * (y**c)" + ] + }, + { + "cell_type": "code", + "execution_count": 218, + "id": "b9bd3a1c", + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.preprocessing import PolynomialFeatures\n", + "from sklearn.linear_model import LinearRegression\n", + "from sklearn.pipeline import make_pipeline" + ] + }, + { + "cell_type": "code", + "execution_count": 220, + "id": "6dedc336", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(2025, 1)" + ] + }, + "execution_count": 220, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X.reshape(-1,1).shape" + ] + }, + { + "cell_type": "code", + "execution_count": 506, + "id": "6121a12b", + "metadata": {}, + "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" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_device_pixel_ratio', {\n", + " device_pixel_ratio: fig.ratio,\n", + " });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute('tabindex', '0');\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;' +\n", + " 'z-index: 2;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'pointer-events: none;' +\n", + " 'position: relative;' +\n", + " 'z-index: 0;'\n", + " );\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'left: 0;' +\n", + " 'pointer-events: none;' +\n", + " 'position: absolute;' +\n", + " 'top: 0;' +\n", + " 'z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " /* This rescales the canvas back to display pixels, so that it\n", + " * appears correct on HiDPI screens. */\n", + " canvas.style.width = width + 'px';\n", + " canvas.style.height = height + 'px';\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " /* User Agent sniffing is bad, but WebKit is busted:\n", + " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", + " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", + " * The worst that happens here is that they get an extra browser\n", + " * selection when dragging, if this check fails to catch them.\n", + " */\n", + " var UA = navigator.userAgent;\n", + " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", + " if(isWebKit) {\n", + " return function (event) {\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We\n", + " * want to control all of the cursor setting manually through\n", + " * the 'cursor' event from matplotlib */\n", + " event.preventDefault()\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " } else {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'dblclick',\n", + " on_mouse_event_closure('dblclick')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " canvas_div.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " canvas_div.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " fig.canvas_div.style.cursor = msg['cursor'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " var img = evt.data;\n", + " if (img.type !== 'image/png') {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " img.type = 'image/png';\n", + " }\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " img\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "function getModifiers(event) {\n", + " var mods = [];\n", + " if (event.ctrlKey) {\n", + " mods.push('ctrl');\n", + " }\n", + " if (event.altKey) {\n", + " mods.push('alt');\n", + " }\n", + " if (event.shiftKey) {\n", + " mods.push('shift');\n", + " }\n", + " if (event.metaKey) {\n", + " mods.push('meta');\n", + " }\n", + " return mods;\n", + "}\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * https://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " // from https://stackoverflow.com/q/1114465\n", + " var boundingRect = this.canvas.getBoundingClientRect();\n", + " var x = (event.clientX - boundingRect.left) * this.ratio;\n", + " var y = (event.clientY - boundingRect.top) * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " modifiers: getModifiers(event),\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.key === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.key;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.key !== 'Control') {\n", + " value += 'ctrl+';\n", + " }\n", + " else if (event.altKey && event.key !== 'Alt') {\n", + " value += 'alt+';\n", + " }\n", + " else if (event.shiftKey && event.key !== 'Shift') {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k' + event.key;\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.binaryType = comm.kernel.ws.binaryType;\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " function updateReadyState(_event) {\n", + " if (comm.kernel.ws) {\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " } else {\n", + " ws.readyState = 3; // Closed state.\n", + " }\n", + " }\n", + " comm.kernel.ws.addEventListener('open', updateReadyState);\n", + " comm.kernel.ws.addEventListener('close', updateReadyState);\n", + " comm.kernel.ws.addEventListener('error', updateReadyState);\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " var data = msg['content']['data'];\n", + " if (data['blob'] !== undefined) {\n", + " data = {\n", + " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", + " };\n", + " }\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(data);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "path = '/Users/rri38/Documents/work/code/tess/strange_things/alpha_star/tess-s0003-1-2_26.017013_-15.937480_90x90_astrocut.fits'\n", + "#path = '/Users/rri38/Documents/work/code/tess/strange_things/alpha_star/'\n", + "tess = tr.tessreduce(tpf=path,calibrate=False)#ra=ra,dec=dec,size=90)#,sector=sector)" + ] + }, + { + "cell_type": "code", + "execution_count": 443, + "id": "246d2dfc", + "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", + "| 21 | 1 | 3 | False | -103 |\n", + "| 44 | 4 | 4 | False | 499 |\n", + "| 46 | 1 | 2 | False | 550 |\n", + "| 72 | 2 | 2 | False | 1259 |\n", + "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" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_device_pixel_ratio', {\n", + " device_pixel_ratio: fig.ratio,\n", + " });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute('tabindex', '0');\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;' +\n", + " 'z-index: 2;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'pointer-events: none;' +\n", + " 'position: relative;' +\n", + " 'z-index: 0;'\n", + " );\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'left: 0;' +\n", + " 'pointer-events: none;' +\n", + " 'position: absolute;' +\n", + " 'top: 0;' +\n", + " 'z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " /* This rescales the canvas back to display pixels, so that it\n", + " * appears correct on HiDPI screens. */\n", + " canvas.style.width = width + 'px';\n", + " canvas.style.height = height + 'px';\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " /* User Agent sniffing is bad, but WebKit is busted:\n", + " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", + " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", + " * The worst that happens here is that they get an extra browser\n", + " * selection when dragging, if this check fails to catch them.\n", + " */\n", + " var UA = navigator.userAgent;\n", + " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", + " if(isWebKit) {\n", + " return function (event) {\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We\n", + " * want to control all of the cursor setting manually through\n", + " * the 'cursor' event from matplotlib */\n", + " event.preventDefault()\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " } else {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'dblclick',\n", + " on_mouse_event_closure('dblclick')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " canvas_div.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " canvas_div.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " fig.canvas_div.style.cursor = msg['cursor'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " var img = evt.data;\n", + " if (img.type !== 'image/png') {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " img.type = 'image/png';\n", + " }\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " img\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "function getModifiers(event) {\n", + " var mods = [];\n", + " if (event.ctrlKey) {\n", + " mods.push('ctrl');\n", + " }\n", + " if (event.altKey) {\n", + " mods.push('alt');\n", + " }\n", + " if (event.shiftKey) {\n", + " mods.push('shift');\n", + " }\n", + " if (event.metaKey) {\n", + " mods.push('meta');\n", + " }\n", + " return mods;\n", + "}\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * https://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " // from https://stackoverflow.com/q/1114465\n", + " var boundingRect = this.canvas.getBoundingClientRect();\n", + " var x = (event.clientX - boundingRect.left) * this.ratio;\n", + " var y = (event.clientY - boundingRect.top) * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " modifiers: getModifiers(event),\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.key === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.key;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.key !== 'Control') {\n", + " value += 'ctrl+';\n", + " }\n", + " else if (event.altKey && event.key !== 'Alt') {\n", + " value += 'alt+';\n", + " }\n", + " else if (event.shiftKey && event.key !== 'Shift') {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k' + event.key;\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.binaryType = comm.kernel.ws.binaryType;\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " function updateReadyState(_event) {\n", + " if (comm.kernel.ws) {\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " } else {\n", + " ws.readyState = 3; // Closed state.\n", + " }\n", + " }\n", + " comm.kernel.ws.addEventListener('open', updateReadyState);\n", + " comm.kernel.ws.addEventListener('close', updateReadyState);\n", + " comm.kernel.ws.addEventListener('error', updateReadyState);\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " var data = msg['content']['data'];\n", + " if (data['blob'] !== undefined) {\n", + " data = {\n", + " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", + " };\n", + " }\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(data);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "obs = tr.spacetime_lookup('08:52:35.241','+28:19:47.34')\n", + "tess = tr.tessreduce(obs_list=obs[1],calibrate=False)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 404, + "id": "f57d3b87", + "metadata": {}, + "outputs": [], + "source": [ + "# https://gist.github.com/amroamroamro/1db8d69b4b65e8bc66a6\n", + "cut = tess.bkg[1000]\n", + "xx = x.reshape(-1,1)\n", + "yy = y.reshape(-1,1)\n", + "zz = cut.reshape(-1,1)\n", + "order = 4\n", + "model = make_pipeline(\n", + " PolynomialFeatures(degree=order),\n", + " LinearRegression(fit_intercept=False))\n", + "model.fit(np.c_[xx, yy], zz)\n", + "\n", + "def names2model(names):\n", + " # C[i] * X^n * Y^m\n", + " return ' + '.join([\n", + " f\"C[{i}]*{n.replace(' ','*')}\"\n", + " for i,n in enumerate(names)])\n", + "\n", + "m = names2model(model[0].get_feature_names_out(['X', 'Y']))\n", + "C = model[1].coef_.T # coefficients\n", + "r2 = model.score(np.c_[xx, yy], zz) # R-squared\n", + "ZZ = model.predict(np.c_[x.flatten(), y.flatten()]).reshape(x.shape)" ] }, + { + "cell_type": "code", + "execution_count": 405, + "id": "152dc330", + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_device_pixel_ratio', {\n", + " device_pixel_ratio: fig.ratio,\n", + " });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute('tabindex', '0');\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;' +\n", + " 'z-index: 2;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'pointer-events: none;' +\n", + " 'position: relative;' +\n", + " 'z-index: 0;'\n", + " );\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'left: 0;' +\n", + " 'pointer-events: none;' +\n", + " 'position: absolute;' +\n", + " 'top: 0;' +\n", + " 'z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " /* This rescales the canvas back to display pixels, so that it\n", + " * appears correct on HiDPI screens. */\n", + " canvas.style.width = width + 'px';\n", + " canvas.style.height = height + 'px';\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " /* User Agent sniffing is bad, but WebKit is busted:\n", + " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", + " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", + " * The worst that happens here is that they get an extra browser\n", + " * selection when dragging, if this check fails to catch them.\n", + " */\n", + " var UA = navigator.userAgent;\n", + " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", + " if(isWebKit) {\n", + " return function (event) {\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We\n", + " * want to control all of the cursor setting manually through\n", + " * the 'cursor' event from matplotlib */\n", + " event.preventDefault()\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " } else {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'dblclick',\n", + " on_mouse_event_closure('dblclick')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " canvas_div.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " canvas_div.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " fig.canvas_div.style.cursor = msg['cursor'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " var img = evt.data;\n", + " if (img.type !== 'image/png') {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " img.type = 'image/png';\n", + " }\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " img\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "function getModifiers(event) {\n", + " var mods = [];\n", + " if (event.ctrlKey) {\n", + " mods.push('ctrl');\n", + " }\n", + " if (event.altKey) {\n", + " mods.push('alt');\n", + " }\n", + " if (event.shiftKey) {\n", + " mods.push('shift');\n", + " }\n", + " if (event.metaKey) {\n", + " mods.push('meta');\n", + " }\n", + " return mods;\n", + "}\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * https://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " // from https://stackoverflow.com/q/1114465\n", + " var boundingRect = this.canvas.getBoundingClientRect();\n", + " var x = (event.clientX - boundingRect.left) * this.ratio;\n", + " var y = (event.clientY - boundingRect.top) * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " modifiers: getModifiers(event),\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.key === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.key;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.key !== 'Control') {\n", + " value += 'ctrl+';\n", + " }\n", + " else if (event.altKey && event.key !== 'Alt') {\n", + " value += 'alt+';\n", + " }\n", + " else if (event.shiftKey && event.key !== 'Shift') {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k' + event.key;\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.binaryType = comm.kernel.ws.binaryType;\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " function updateReadyState(_event) {\n", + " if (comm.kernel.ws) {\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " } else {\n", + " ws.readyState = 3; // Closed state.\n", + " }\n", + " }\n", + " comm.kernel.ws.addEventListener('open', updateReadyState);\n", + " comm.kernel.ws.addEventListener('close', updateReadyState);\n", + " comm.kernel.ws.addEventListener('error', updateReadyState);\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " var data = msg['content']['data'];\n", + " if (data['blob'] !== undefined) {\n", + " data = {\n", + " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", + " };\n", + " }\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(data);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 405, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "plt.figure()\n", + "plt.subplot(131)\n", + "plt.imshow(ZZ)#,vmin=100,vmax=120)\n", + "plt.subplot(132)\n", + "plt.imshow(cut)#,vmin=100,vmax=120)\n", + "plt.subplot(133)\n", + "plt.imshow(cut-ZZ,vmin=-10,vmax=10)" + ] + }, + { + "cell_type": "code", + "execution_count": 282, + "id": "3dfe6312", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 339, + "id": "40a63958", + "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", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " /* This rescales the canvas back to display pixels, so that it\n", + " * appears correct on HiDPI screens. */\n", + " canvas.style.width = width + 'px';\n", + " canvas.style.height = height + 'px';\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " /* User Agent sniffing is bad, but WebKit is busted:\n", + " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", + " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", + " * The worst that happens here is that they get an extra browser\n", + " * selection when dragging, if this check fails to catch them.\n", + " */\n", + " var UA = navigator.userAgent;\n", + " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", + " if(isWebKit) {\n", + " return function (event) {\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We\n", + " * want to control all of the cursor setting manually through\n", + " * the 'cursor' event from matplotlib */\n", + " event.preventDefault()\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " } else {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'dblclick',\n", + " on_mouse_event_closure('dblclick')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " canvas_div.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " canvas_div.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " fig.canvas_div.style.cursor = msg['cursor'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " var img = evt.data;\n", + " if (img.type !== 'image/png') {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " img.type = 'image/png';\n", + " }\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " img\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "function getModifiers(event) {\n", + " var mods = [];\n", + " if (event.ctrlKey) {\n", + " mods.push('ctrl');\n", + " }\n", + " if (event.altKey) {\n", + " mods.push('alt');\n", + " }\n", + " if (event.shiftKey) {\n", + " mods.push('shift');\n", + " }\n", + " if (event.metaKey) {\n", + " mods.push('meta');\n", + " }\n", + " return mods;\n", + "}\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * https://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " // from https://stackoverflow.com/q/1114465\n", + " var boundingRect = this.canvas.getBoundingClientRect();\n", + " var x = (event.clientX - boundingRect.left) * this.ratio;\n", + " var y = (event.clientY - boundingRect.top) * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " modifiers: getModifiers(event),\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.key === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.key;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.key !== 'Control') {\n", + " value += 'ctrl+';\n", + " }\n", + " else if (event.altKey && event.key !== 'Alt') {\n", + " value += 'alt+';\n", + " }\n", + " else if (event.shiftKey && event.key !== 'Shift') {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k' + event.key;\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.binaryType = comm.kernel.ws.binaryType;\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " function updateReadyState(_event) {\n", + " if (comm.kernel.ws) {\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " } else {\n", + " ws.readyState = 3; // Closed state.\n", + " }\n", + " }\n", + " comm.kernel.ws.addEventListener('open', updateReadyState);\n", + " comm.kernel.ws.addEventListener('close', updateReadyState);\n", + " comm.kernel.ws.addEventListener('error', updateReadyState);\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " var data = msg['content']['data'];\n", + " if (data['blob'] !== undefined) {\n", + " data = {\n", + " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", + " };\n", + " }\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(data);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 339, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "plt.figure()\n", + "plt.imshow(tess.ref,vmax=100)" + ] + }, + { + "cell_type": "code", + "execution_count": 345, + "id": "050841b3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 1., 1., 1., ..., nan, nan, 1.],\n", + " [ 1., 1., 1., ..., nan, nan, 1.],\n", + " [ 1., 1., 1., ..., nan, nan, 1.],\n", + " ...,\n", + " [ 1., 1., 1., ..., nan, nan, nan],\n", + " [ 1., 1., 1., ..., 1., 1., 1.],\n", + " [ 1., 1., nan, ..., 1., 1., 1.]])" + ] + }, + "execution_count": 345, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 488, + "id": "ccbb90b6", + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_device_pixel_ratio', {\n", + " device_pixel_ratio: fig.ratio,\n", + " });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute('tabindex', '0');\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;' +\n", + " 'z-index: 2;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'pointer-events: none;' +\n", + " 'position: relative;' +\n", + " 'z-index: 0;'\n", + " );\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'left: 0;' +\n", + " 'pointer-events: none;' +\n", + " 'position: absolute;' +\n", + " 'top: 0;' +\n", + " 'z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " /* This rescales the canvas back to display pixels, so that it\n", + " * appears correct on HiDPI screens. */\n", + " canvas.style.width = width + 'px';\n", + " canvas.style.height = height + 'px';\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " /* User Agent sniffing is bad, but WebKit is busted:\n", + " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", + " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", + " * The worst that happens here is that they get an extra browser\n", + " * selection when dragging, if this check fails to catch them.\n", + " */\n", + " var UA = navigator.userAgent;\n", + " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", + " if(isWebKit) {\n", + " return function (event) {\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We\n", + " * want to control all of the cursor setting manually through\n", + " * the 'cursor' event from matplotlib */\n", + " event.preventDefault()\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " } else {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'dblclick',\n", + " on_mouse_event_closure('dblclick')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " canvas_div.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " canvas_div.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " fig.canvas_div.style.cursor = msg['cursor'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " var img = evt.data;\n", + " if (img.type !== 'image/png') {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " img.type = 'image/png';\n", + " }\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " img\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "function getModifiers(event) {\n", + " var mods = [];\n", + " if (event.ctrlKey) {\n", + " mods.push('ctrl');\n", + " }\n", + " if (event.altKey) {\n", + " mods.push('alt');\n", + " }\n", + " if (event.shiftKey) {\n", + " mods.push('shift');\n", + " }\n", + " if (event.metaKey) {\n", + " mods.push('meta');\n", + " }\n", + " return mods;\n", + "}\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * https://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " // from https://stackoverflow.com/q/1114465\n", + " var boundingRect = this.canvas.getBoundingClientRect();\n", + " var x = (event.clientX - boundingRect.left) * this.ratio;\n", + " var y = (event.clientY - boundingRect.top) * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " modifiers: getModifiers(event),\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.key === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.key;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.key !== 'Control') {\n", + " value += 'ctrl+';\n", + " }\n", + " else if (event.altKey && event.key !== 'Alt') {\n", + " value += 'alt+';\n", + " }\n", + " else if (event.shiftKey && event.key !== 'Shift') {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k' + event.key;\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.binaryType = comm.kernel.ws.binaryType;\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " function updateReadyState(_event) {\n", + " if (comm.kernel.ws) {\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " } else {\n", + " ws.readyState = 3; // Closed state.\n", + " }\n", + " }\n", + " comm.kernel.ws.addEventListener('open', updateReadyState);\n", + " comm.kernel.ws.addEventListener('close', updateReadyState);\n", + " comm.kernel.ws.addEventListener('error', updateReadyState);\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " var data = msg['content']['data'];\n", + " if (data['blob'] !== undefined) {\n", + " data = {\n", + " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", + " };\n", + " }\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(data);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 488, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "plt.figure()\n", + "plt.plot(tess.bkg[:,10,10])" + ] + }, + { + "cell_type": "code", + "execution_count": 504, + "id": "e4422f46", + "metadata": {}, + "outputs": [], + "source": [ + "sm = tess._bkgmask\n", + "x, y = np.meshgrid(np.arange(0,size), np.arange(0,size))\n", + "# https://gist.github.com/amroamroamro/1db8d69b4b65e8bc66a6\n", + "i = 100\n", + "cut = tess.bkg[i]\n", + "masked = cut * sm[i]\n", + "xx = x.reshape(-1,1)\n", + "yy = y.reshape(-1,1)\n", + "zz = cut.reshape(-1,1)\n", + "ind = np.where(np.isfinite(zz))\n", + "order = 4\n", + "model = make_pipeline(\n", + " PolynomialFeatures(degree=order),\n", + " LinearRegression(fit_intercept=False))\n", + "model.fit(np.c_[xx[ind], yy[ind]], zz[ind])\n", + "\n", + "def names2model(names):\n", + " # C[i] * X^n * Y^m\n", + " return ' + '.join([\n", + " f\"C[{i}]*{n.replace(' ','*')}\"\n", + " for i,n in enumerate(names)])\n", + "\n", + "m = names2model(model[0].get_feature_names_out(['X', 'Y']))\n", + "C = model[1].coef_.T # coefficients\n", + "r2 = model.score(np.c_[xx, yy], zz) # R-squared\n", + "ZZ = model.predict(np.c_[x.flatten(), y.flatten()]).reshape(x.shape)\n", + "\n", + "diff = cut - ZZ\n", + "m,me, s = sigma_clipped_stats(diff,maxiters=10)\n", + "cut_ind = np.where((diff >= (me+2*s)) | \n", + " (diff <= (me-2*s)))\n", + "\n", + "bkg2 = tr.deepcopy(cut)\n", + "bkg2[cut_ind] = ZZ[cut_ind]\n", + "#bkg2 = ZZ" + ] + }, + { + "cell_type": "code", + "execution_count": 505, + "id": "9a775b2a", + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_device_pixel_ratio', {\n", + " device_pixel_ratio: fig.ratio,\n", + " });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute('tabindex', '0');\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;' +\n", + " 'z-index: 2;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'pointer-events: none;' +\n", + " 'position: relative;' +\n", + " 'z-index: 0;'\n", + " );\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'left: 0;' +\n", + " 'pointer-events: none;' +\n", + " 'position: absolute;' +\n", + " 'top: 0;' +\n", + " 'z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " /* This rescales the canvas back to display pixels, so that it\n", + " * appears correct on HiDPI screens. */\n", + " canvas.style.width = width + 'px';\n", + " canvas.style.height = height + 'px';\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " /* User Agent sniffing is bad, but WebKit is busted:\n", + " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", + " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", + " * The worst that happens here is that they get an extra browser\n", + " * selection when dragging, if this check fails to catch them.\n", + " */\n", + " var UA = navigator.userAgent;\n", + " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", + " if(isWebKit) {\n", + " return function (event) {\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We\n", + " * want to control all of the cursor setting manually through\n", + " * the 'cursor' event from matplotlib */\n", + " event.preventDefault()\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " } else {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'dblclick',\n", + " on_mouse_event_closure('dblclick')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " canvas_div.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " canvas_div.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " fig.canvas_div.style.cursor = msg['cursor'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " var img = evt.data;\n", + " if (img.type !== 'image/png') {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " img.type = 'image/png';\n", + " }\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " img\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "function getModifiers(event) {\n", + " var mods = [];\n", + " if (event.ctrlKey) {\n", + " mods.push('ctrl');\n", + " }\n", + " if (event.altKey) {\n", + " mods.push('alt');\n", + " }\n", + " if (event.shiftKey) {\n", + " mods.push('shift');\n", + " }\n", + " if (event.metaKey) {\n", + " mods.push('meta');\n", + " }\n", + " return mods;\n", + "}\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * https://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " // from https://stackoverflow.com/q/1114465\n", + " var boundingRect = this.canvas.getBoundingClientRect();\n", + " var x = (event.clientX - boundingRect.left) * this.ratio;\n", + " var y = (event.clientY - boundingRect.top) * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " modifiers: getModifiers(event),\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.key === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.key;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.key !== 'Control') {\n", + " value += 'ctrl+';\n", + " }\n", + " else if (event.altKey && event.key !== 'Alt') {\n", + " value += 'alt+';\n", + " }\n", + " else if (event.shiftKey && event.key !== 'Shift') {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k' + event.key;\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.binaryType = comm.kernel.ws.binaryType;\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " function updateReadyState(_event) {\n", + " if (comm.kernel.ws) {\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " } else {\n", + " ws.readyState = 3; // Closed state.\n", + " }\n", + " }\n", + " comm.kernel.ws.addEventListener('open', updateReadyState);\n", + " comm.kernel.ws.addEventListener('close', updateReadyState);\n", + " comm.kernel.ws.addEventListener('error', updateReadyState);\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " var data = msg['content']['data'];\n", + " if (data['blob'] !== undefined) {\n", + " data = {\n", + " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", + " };\n", + " }\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(data);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_device_pixel_ratio', {\n", + " device_pixel_ratio: fig.ratio,\n", + " });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute('tabindex', '0');\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;' +\n", + " 'z-index: 2;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'pointer-events: none;' +\n", + " 'position: relative;' +\n", + " 'z-index: 0;'\n", + " );\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'left: 0;' +\n", + " 'pointer-events: none;' +\n", + " 'position: absolute;' +\n", + " 'top: 0;' +\n", + " 'z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " /* This rescales the canvas back to display pixels, so that it\n", + " * appears correct on HiDPI screens. */\n", + " canvas.style.width = width + 'px';\n", + " canvas.style.height = height + 'px';\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " /* User Agent sniffing is bad, but WebKit is busted:\n", + " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", + " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", + " * The worst that happens here is that they get an extra browser\n", + " * selection when dragging, if this check fails to catch them.\n", + " */\n", + " var UA = navigator.userAgent;\n", + " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", + " if(isWebKit) {\n", + " return function (event) {\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We\n", + " * want to control all of the cursor setting manually through\n", + " * the 'cursor' event from matplotlib */\n", + " event.preventDefault()\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " } else {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'dblclick',\n", + " on_mouse_event_closure('dblclick')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " canvas_div.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " canvas_div.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " fig.canvas_div.style.cursor = msg['cursor'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " var img = evt.data;\n", + " if (img.type !== 'image/png') {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " img.type = 'image/png';\n", + " }\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " img\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "function getModifiers(event) {\n", + " var mods = [];\n", + " if (event.ctrlKey) {\n", + " mods.push('ctrl');\n", + " }\n", + " if (event.altKey) {\n", + " mods.push('alt');\n", + " }\n", + " if (event.shiftKey) {\n", + " mods.push('shift');\n", + " }\n", + " if (event.metaKey) {\n", + " mods.push('meta');\n", + " }\n", + " return mods;\n", + "}\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * https://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " // from https://stackoverflow.com/q/1114465\n", + " var boundingRect = this.canvas.getBoundingClientRect();\n", + " var x = (event.clientX - boundingRect.left) * this.ratio;\n", + " var y = (event.clientY - boundingRect.top) * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " modifiers: getModifiers(event),\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.key === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.key;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.key !== 'Control') {\n", + " value += 'ctrl+';\n", + " }\n", + " else if (event.altKey && event.key !== 'Alt') {\n", + " value += 'alt+';\n", + " }\n", + " else if (event.shiftKey && event.key !== 'Shift') {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k' + event.key;\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.binaryType = comm.kernel.ws.binaryType;\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " function updateReadyState(_event) {\n", + " if (comm.kernel.ws) {\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " } else {\n", + " ws.readyState = 3; // Closed state.\n", + " }\n", + " }\n", + " comm.kernel.ws.addEventListener('open', updateReadyState);\n", + " comm.kernel.ws.addEventListener('close', updateReadyState);\n", + " comm.kernel.ws.addEventListener('error', updateReadyState);\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " var data = msg['content']['data'];\n", + " if (data['blob'] !== undefined) {\n", + " data = {\n", + " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", + " };\n", + " }\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(data);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 505, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "plt.figure()\n", + "plt.subplot(221)\n", + "plt.imshow(ZZ)#,vmin=100,vmax=120)\n", + "plt.subplot(222)\n", + "plt.imshow(cut)#,vmin=100,vmax=120)\n", + "plt.subplot(223)\n", + "plt.imshow(cut-ZZ)#,vmin=-10,vmax=10)\n", + "plt.plot(cut_ind[1],cut_ind[0],'C1.')\n", + "plt.subplot(224)\n", + "plt.imshow(bkg2)\n", + "#plt.plot(cut_ind[1],cut_ind[0],'C1.')\n", + "\n", + "plt.figure()\n", + "plt.subplot(121)\n", + "plt.title('new')\n", + "plt.imshow(tess.flux[i]+tess.bkg[i]-bkg2,vmin=-10,vmax=10)\n", + "plt.subplot(122)\n", + "plt.title('old')\n", + "plt.imshow(tess.flux[i],vmin=-10,vmax=10)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "65457757", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "78619add", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 235, + "id": "1646b569", + "metadata": {}, + "outputs": [], + "source": [ + "flux = tess.bkg[1000]\n", + "size = 90\n", + "sx, sy = flux.shape\n", + "X, Y = np.ogrid[0:sx, 0:sy]\n", + "regions = sy//size * (X//size) + Y//size\n", + "max_reg = np.max(regions)\n", + "\n", + "clip = np.zeros_like(flux)\n", + "for i in range(max_reg+1):\n", + " rx,ry = np.where(regions == i)\n", + " cut = flux[ry,rx].reshape(size,size)\n", + " x, y = np.meshgrid(np.arange(0,size), np.arange(0,size))\n", + " parameters, covariance = curve_fit(function, [y.ravel(),x.ravel()], cut.ravel())\n", + " z = function(np.array([y, x]), *parameters)\n", + " diff = (cut-z)#.ravel()\n", + " m,me, s = sigma_clipped_stats(diff,maxiters=5)\n", + " cut_ind = np.where((diff >= (me+2*s)) | \n", + " (diff <= (me-2*s)))\n", + " #clip[rx[cut_ind[0]],ry[cut_ind[0]]] = 1\n" + ] + }, + { + "cell_type": "code", + "execution_count": 236, + "id": "2f555d7d", + "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", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " /* This rescales the canvas back to display pixels, so that it\n", + " * appears correct on HiDPI screens. */\n", + " canvas.style.width = width + 'px';\n", + " canvas.style.height = height + 'px';\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " /* User Agent sniffing is bad, but WebKit is busted:\n", + " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", + " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", + " * The worst that happens here is that they get an extra browser\n", + " * selection when dragging, if this check fails to catch them.\n", + " */\n", + " var UA = navigator.userAgent;\n", + " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", + " if(isWebKit) {\n", + " return function (event) {\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We\n", + " * want to control all of the cursor setting manually through\n", + " * the 'cursor' event from matplotlib */\n", + " event.preventDefault()\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " } else {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'dblclick',\n", + " on_mouse_event_closure('dblclick')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " canvas_div.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " canvas_div.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " fig.canvas_div.style.cursor = msg['cursor'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " var img = evt.data;\n", + " if (img.type !== 'image/png') {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " img.type = 'image/png';\n", + " }\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " img\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "function getModifiers(event) {\n", + " var mods = [];\n", + " if (event.ctrlKey) {\n", + " mods.push('ctrl');\n", + " }\n", + " if (event.altKey) {\n", + " mods.push('alt');\n", + " }\n", + " if (event.shiftKey) {\n", + " mods.push('shift');\n", + " }\n", + " if (event.metaKey) {\n", + " mods.push('meta');\n", + " }\n", + " return mods;\n", + "}\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * https://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " // from https://stackoverflow.com/q/1114465\n", + " var boundingRect = this.canvas.getBoundingClientRect();\n", + " var x = (event.clientX - boundingRect.left) * this.ratio;\n", + " var y = (event.clientY - boundingRect.top) * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " modifiers: getModifiers(event),\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.key === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.key;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.key !== 'Control') {\n", + " value += 'ctrl+';\n", + " }\n", + " else if (event.altKey && event.key !== 'Alt') {\n", + " value += 'alt+';\n", + " }\n", + " else if (event.shiftKey && event.key !== 'Shift') {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k' + event.key;\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.binaryType = comm.kernel.ws.binaryType;\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " function updateReadyState(_event) {\n", + " if (comm.kernel.ws) {\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " } else {\n", + " ws.readyState = 3; // Closed state.\n", + " }\n", + " }\n", + " comm.kernel.ws.addEventListener('open', updateReadyState);\n", + " comm.kernel.ws.addEventListener('close', updateReadyState);\n", + " comm.kernel.ws.addEventListener('error', updateReadyState);\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " var data = msg['content']['data'];\n", + " if (data['blob'] !== undefined) {\n", + " data = {\n", + " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", + " };\n", + " }\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(data);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 236, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "plt.figure()\n", + "plt.imshow(diff.reshape(size,size))\n", + "plt.plot(cut_ind[1],cut_ind[0],'C1.')" + ] + }, + { + "cell_type": "code", + "execution_count": 194, + "id": "b794c235", + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_device_pixel_ratio', {\n", + " device_pixel_ratio: fig.ratio,\n", + " });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute('tabindex', '0');\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;' +\n", + " 'z-index: 2;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'pointer-events: none;' +\n", + " 'position: relative;' +\n", + " 'z-index: 0;'\n", + " );\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'left: 0;' +\n", + " 'pointer-events: none;' +\n", + " 'position: absolute;' +\n", + " 'top: 0;' +\n", + " 'z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " /* This rescales the canvas back to display pixels, so that it\n", + " * appears correct on HiDPI screens. */\n", + " canvas.style.width = width + 'px';\n", + " canvas.style.height = height + 'px';\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " /* User Agent sniffing is bad, but WebKit is busted:\n", + " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", + " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", + " * The worst that happens here is that they get an extra browser\n", + " * selection when dragging, if this check fails to catch them.\n", + " */\n", + " var UA = navigator.userAgent;\n", + " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", + " if(isWebKit) {\n", + " return function (event) {\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We\n", + " * want to control all of the cursor setting manually through\n", + " * the 'cursor' event from matplotlib */\n", + " event.preventDefault()\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " } else {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'dblclick',\n", + " on_mouse_event_closure('dblclick')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " canvas_div.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " canvas_div.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " fig.canvas_div.style.cursor = msg['cursor'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " var img = evt.data;\n", + " if (img.type !== 'image/png') {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " img.type = 'image/png';\n", + " }\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " img\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "function getModifiers(event) {\n", + " var mods = [];\n", + " if (event.ctrlKey) {\n", + " mods.push('ctrl');\n", + " }\n", + " if (event.altKey) {\n", + " mods.push('alt');\n", + " }\n", + " if (event.shiftKey) {\n", + " mods.push('shift');\n", + " }\n", + " if (event.metaKey) {\n", + " mods.push('meta');\n", + " }\n", + " return mods;\n", + "}\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * https://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " // from https://stackoverflow.com/q/1114465\n", + " var boundingRect = this.canvas.getBoundingClientRect();\n", + " var x = (event.clientX - boundingRect.left) * this.ratio;\n", + " var y = (event.clientY - boundingRect.top) * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " modifiers: getModifiers(event),\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.key === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.key;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.key !== 'Control') {\n", + " value += 'ctrl+';\n", + " }\n", + " else if (event.altKey && event.key !== 'Alt') {\n", + " value += 'alt+';\n", + " }\n", + " else if (event.shiftKey && event.key !== 'Shift') {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k' + event.key;\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.binaryType = comm.kernel.ws.binaryType;\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " function updateReadyState(_event) {\n", + " if (comm.kernel.ws) {\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " } else {\n", + " ws.readyState = 3; // Closed state.\n", + " }\n", + " }\n", + " comm.kernel.ws.addEventListener('open', updateReadyState);\n", + " comm.kernel.ws.addEventListener('close', updateReadyState);\n", + " comm.kernel.ws.addEventListener('error', updateReadyState);\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " var data = msg['content']['data'];\n", + " if (data['blob'] !== undefined) {\n", + " data = {\n", + " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", + " };\n", + " }\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(data);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 194, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "plt.figure()\n", + "plt.imshow(clip)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "07ea7694", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 181, + "id": "0c97d49b", + "metadata": {}, + "outputs": [], + "source": [ + "test = flux[ry,rx].reshape(size,size)\n", + "X, Y = np.meshgrid(np.arange(0,30), np.arange(0,30))\n", + "Z = test.ravel()" + ] + }, + { + "cell_type": "code", + "execution_count": 179, + "id": "c21aa3a3", + "metadata": {}, + "outputs": [], + "source": [ + "test = tess.bkg\n", + "X, Y = np.meshgrid(np.arange(0,90), np.arange(0,90))\n", + "Z = test[100].ravel()" + ] + }, + { + "cell_type": "code", + "execution_count": 154, + "id": "a353bd9d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([], dtype=int64),)" + ] + }, + "execution_count": 154, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.where(~np.isfinite(Z))" + ] + }, + { + "cell_type": "code", + "execution_count": 183, + "id": "316d6a5e", + "metadata": {}, + "outputs": [], + "source": [ + "parameters, covariance = curve_fit(function, [Y.ravel(),X.ravel()], Z)" + ] + }, + { + "cell_type": "code", + "execution_count": 184, + "id": "97e989d8", + "metadata": {}, + "outputs": [], + "source": [ + "z = function(np.array([Y+1, X+1]), *parameters)" + ] + }, + { + "cell_type": "code", + "execution_count": 186, + "id": "3fd917fa", + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_device_pixel_ratio', {\n", + " device_pixel_ratio: fig.ratio,\n", + " });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute('tabindex', '0');\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;' +\n", + " 'z-index: 2;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'pointer-events: none;' +\n", + " 'position: relative;' +\n", + " 'z-index: 0;'\n", + " );\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'left: 0;' +\n", + " 'pointer-events: none;' +\n", + " 'position: absolute;' +\n", + " 'top: 0;' +\n", + " 'z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " /* This rescales the canvas back to display pixels, so that it\n", + " * appears correct on HiDPI screens. */\n", + " canvas.style.width = width + 'px';\n", + " canvas.style.height = height + 'px';\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " /* User Agent sniffing is bad, but WebKit is busted:\n", + " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", + " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", + " * The worst that happens here is that they get an extra browser\n", + " * selection when dragging, if this check fails to catch them.\n", + " */\n", + " var UA = navigator.userAgent;\n", + " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", + " if(isWebKit) {\n", + " return function (event) {\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We\n", + " * want to control all of the cursor setting manually through\n", + " * the 'cursor' event from matplotlib */\n", + " event.preventDefault()\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " } else {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'dblclick',\n", + " on_mouse_event_closure('dblclick')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " canvas_div.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " canvas_div.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " canvas_div.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " fig.canvas_div.style.cursor = msg['cursor'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " var img = evt.data;\n", + " if (img.type !== 'image/png') {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " img.type = 'image/png';\n", + " }\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " img\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "function getModifiers(event) {\n", + " var mods = [];\n", + " if (event.ctrlKey) {\n", + " mods.push('ctrl');\n", + " }\n", + " if (event.altKey) {\n", + " mods.push('alt');\n", + " }\n", + " if (event.shiftKey) {\n", + " mods.push('shift');\n", + " }\n", + " if (event.metaKey) {\n", + " mods.push('meta');\n", + " }\n", + " return mods;\n", + "}\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * https://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " // from https://stackoverflow.com/q/1114465\n", + " var boundingRect = this.canvas.getBoundingClientRect();\n", + " var x = (event.clientX - boundingRect.left) * this.ratio;\n", + " var y = (event.clientY - boundingRect.top) * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " modifiers: getModifiers(event),\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.key === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.key;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.key !== 'Control') {\n", + " value += 'ctrl+';\n", + " }\n", + " else if (event.altKey && event.key !== 'Alt') {\n", + " value += 'alt+';\n", + " }\n", + " else if (event.shiftKey && event.key !== 'Shift') {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k' + event.key;\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.binaryType = comm.kernel.ws.binaryType;\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " function updateReadyState(_event) {\n", + " if (comm.kernel.ws) {\n", + " ws.readyState = comm.kernel.ws.readyState;\n", + " } else {\n", + " ws.readyState = 3; // Closed state.\n", + " }\n", + " }\n", + " comm.kernel.ws.addEventListener('open', updateReadyState);\n", + " comm.kernel.ws.addEventListener('close', updateReadyState);\n", + " comm.kernel.ws.addEventListener('error', updateReadyState);\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " var data = msg['content']['data'];\n", + " if (data['blob'] !== undefined) {\n", + " data = {\n", + " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", + " };\n", + " }\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(data);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 186, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "plt.figure()\n", + "plt.subplot(131)\n", + "plt.imshow(z,vmin=100,vmax=120)\n", + "plt.subplot(132)\n", + "plt.imshow(test,vmin=100,vmax=120)\n", + "plt.subplot(133)\n", + "plt.imshow(test-z,vmin=-10,vmax=10)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "600769ed", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f7058191", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 87, + "id": "a79cca56", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "image/png": "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PN4WZRFCe/fu1caNG7V582adOHFC9957rzo7O3X27FnfS4vU7bffrsHBwdzl5MmTvpdUcGNjY1q4cKF27NhxzdtfeOEFbdu2TTt27NCxY8eUTCb1wAMP5DoGy9H19lmSHnzwwSnH/sCBA0VcYeH19fVp3bp1Onr0qHp6ejQxMaGOjg6NjY3lxlTisc5nv6XKO94mrgx8//vfd08++eSU677zne+4X/ziF55WFL3nnnvOLVy40PcyikqSe/3113NfZ7NZl0wm3fPPP5+77uuvv3aJRML9/ve/97DCwrtyn51zbs2aNe6hhx7ysp5iGR4edpJcX1+fc25mHGvnrt5v52bG8Z5OyZ8JjY+P6/jx4+ro6JhyfUdHh44cOeJpVcVx+vRpNTc3q62tTY888og+/fRT30sqqv7+fg0NDU059rFYTPfff3/FH/ve3l41Njbqtttu0+OPP67hYXuDcSkbGRmRJDU0NEiaOcf6yv2+rNKP93RKPoQ+//xzTU5Oqqmpacr1TU1NGhoa8rSq6C1atEi7d+/WwYMH9fLLL2toaEhLlizRuXPnfC+taC4f35l27Ds7O/Xqq6/q0KFDevHFF3Xs2DEtX75cmYztb+uUKuecurq6tHTpUi1YsEDSzDjW19pvqfKP9/WUXIv2N7nyzzo45666rpJ0dnbm/n3HHXfonnvu0a233qpXXnlFXV1dHldWfDPt2K9evTr37wULFuiuu+5Sa2ur9u/fr1WrVnlcWWGsX79eH374od57772rbqvkY/1N+13px/t6Sv5MaO7cuaqurr7qf0PDw8NX/a+pks2ZM0d33HGHTp8+7XspRXP53YAz/dinUim1trZWxLHfsGGD3nzzTb377rtT/mRLpR/rb9rva6mk452Pkg+huro63Xnnnerp6ZlyfU9Pj5YsWeJpVcWXyWT00UcfKZVK+V5K0bS1tSmZTE459uPj4+rr65tRx/7cuXMaGBgo62PvnNP69eu1b98+HTp0SG1tbVNur9Rjfb39vpZKON4mHt8UkbfXXnvN1dbWuj/+8Y/un//8p9u4caObM2eOO3PmjO+lRebpp592vb297tNPP3VHjx51P/jBD1w8Hq+4fR4dHXUnTpxwJ06ccJLctm3b3IkTJ9y//vUv55xzzz//vEskEm7fvn3u5MmT7tFHH3WpVMql02nPKw9vun0eHR11Tz/9tDty5Ijr7+937777rrvnnnvct7/97bLe55///OcukUi43t5eNzg4mLt89dVXuTGVeKyvt9+VerwtyiKEnHPud7/7nWttbXV1dXXue9/73pS3OFai1atXu1Qq5Wpra11zc7NbtWqVO3XqlO9lFdy7777rJF11WbNmjXPu0lt3n3vuOZdMJl0sFnP33XefO3nypN9F36Dp9vmrr75yHR0d7uabb3a1tbXulltucWvWrHFnz571vewbcq39leR27dqVG1OJx/p6+12px9uCP+UAAPCm5F8TAgBULkIIAOANIQQA8IYQAgB4QwgBALwhhAAA3hBCAABvCCEAgDeEEADAG0IIAOANIQQA8IYQAgB489++pRV7vw5MKAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import numpy as np\n", + "from scipy.optimize import curve_fit\n", + "from mpl_toolkits.mplot3d import Axes3D\n", + "import matplotlib.pyplot as plt\n", + "\n", + "\n", + "# test function\n", + "def function(data, a, b, c):\n", + " x = data[0]\n", + " y = data[1]\n", + " return a * (x**b) * (y**c)\n", + "\n", + "# setup test data\n", + "raw_data = [2.0, 2.0, 2.0], [1.5, 1.5, 1.5], [0.5, 0.5, 0.5],[3.0, 2.0, 1.0], [3.0, 2.0, 1.0],\\\n", + " [3.0, 2.0, 1.0], [2.4, 2.5, 2.2], [2.4, 3.0, 2.5], [4.0, 3.3, 8.0]\n", + "\n", + "# convert data into proper format\n", + "x_data = []\n", + "y_data = []\n", + "z_data = []\n", + "for item in raw_data:\n", + " x_data.append(item[0])\n", + " y_data.append(item[1])\n", + " z_data.append(item[2])\n", + "\n", + "# get fit parameters from scipy curve fit\n", + "\n", + "parameters, covariance = curve_fit(function, [np.arange(0,90), y_data], z_data)\n", + "\n", + "# create surface function model\n", + "# setup data points for calculating surface model\n", + "model_x_data = np.linspace(min(x_data), max(x_data), 30)\n", + "model_y_data = np.linspace(min(y_data), max(y_data), 30)\n", + "# create coordinate arrays for vectorized evaluations\n", + "X, Y = np.meshgrid(model_x_data, model_y_data)\n", + "# calculate Z coordinate array\n", + "Z = function(np.array([X, Y]), *parameters)\n", + "plt.figure()\n", + "plt.imshow(Z)\n", + "# setup figure object\n", + "fig = plt.figure()\n", + "# setup 3d object\n", + "ax = Axes3D(fig)\n", + "# plot surface\n", + "ax.plot_surface(X, Y, Z)\n", + "# plot input data\n", + "ax.scatter(x_data, y_data, z_data, color='red')\n", + "# set plot descriptions\n", + "ax.set_xlabel('X data')\n", + "ax.set_ylabel('Y data')\n", + "ax.set_zlabel('Z data')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "0e273bde", + "metadata": {}, + "outputs": [], + "source": [ + "cut_ind = np.where((flux[:,rx,ry] >= (me+2*s)[:,np.newaxis]) | (flux[:,rx,ry] <= (me-2*s)[:,np.newaxis]))\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "310ea539", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([ 40, 40, 40, ..., 1234, 1234, 1234]),\n", + " array([ 3, 23, 24, ..., 2000, 2011, 2024]))" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cut_ind" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "d40d0fdd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(1235, 2025)" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tess.flux[:,ry,rx].shape" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "20f92ad1", + "metadata": {}, + "outputs": [], + "source": [ + "m,me, s = sigma_clipped_stats(tess.flux[:,ry,rx],maxiters=10,axis=(1))" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "8d27883d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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VQUAcDgcWLt2Ld577z1UVlaiXbt2GDt2LD788EOkpqYa2VQiItMa0z14tpsontgEQRBi3YhIqq6uhsvlQlVVFdLS0mLdHCIiItIhlO9vrm1ERERElsLghYiIiCyFwQsRERFZCoMXIiIishQGL0RERGQpDF6IiIjIUhi8EBERkaUweCEiIiJLYfBCRERElsLghYiIiCyFwQsRERFZCoMXIiIishRDV5WOBe86k9XV1TFuCREREenl/d7Ws150kwtejh49CgDIycmJcUuIiIgoVEePHoXL5dLcxiboCXEsxO12Y+/evUhNTYXNZgt4vrq6Gjk5OSgrKwu65Ha847EKDY+XfjxWoeHxCg2Pl35mOlaCIODo0aPIzs6G3a49qqXJZV7sdjs6dOgQdLu0tLSY/4+yCh6r0PB46cdjFRoer9DweOlnlmMVLOPixQG7REREZCkMXoiIiMhS4i54cTqdeOqpp+B0OmPdFNPjsQoNj5d+PFah4fEKDY+XflY9Vk1uwC4RERE1bXGXeSEiIiJrY/BCRERElsLghYiIiCyFwQsRERFZSlwFLy+//DK6dOmC5ORkDBkyBMuWLYt1k6Ju5syZOOuss5CamorMzExcdtllKC0tlWwjCAJmzJiB7OxsNGvWDOeddx7Wr18v2aampgb33HMPMjIykJKSgksvvRS7d++O5keJupkzZ8Jms+H+++/3PcZjJbVnzx5cf/31aN26NZo3b46BAwdi5cqVvud5vPzq6+vx5JNPokuXLmjWrBm6du2Kp59+Gm6327dNvB6vpUuX4pJLLkF2djZsNhs+++wzyfOROi4VFRXIy8uDy+WCy+VCXl4eKisrDf50kad1vOrq6vDoo4+if//+SElJQXZ2Nm644Qbs3btX8h6WO15CnPjggw+ExMREYfbs2cKGDRuE++67T0hJSRF27twZ66ZF1fjx44W3335bWLdunVBSUiJMnDhR6Nixo3Ds2DHfNs8++6yQmpoqfPLJJ8LatWuFa665RmjXrp1QXV3t2+aOO+4Q2rdvLyxYsEBYtWqVMHbsWOHMM88U6uvrY/GxDLd8+XKhc+fOwoABA4T77rvP9ziPld+RI0eETp06CTfddJNQXFwsbN++Xfj++++FrVu3+rbh8fJ75plnhNatWwtfffWVsH37duG///2v0KJFC+H555/3bROvx+ubb74Rnnji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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure()\n", + "plt.plot(m)" + ] + }, + { + "cell_type": "markdown", + "id": "0a4ebcfb", + "metadata": {}, + "source": [] + }, { "cell_type": "code", "execution_count": 93, - "id": "7c3de227-2179-42e6-9b16-a24edf03b680", + "id": "07314d86", "metadata": {}, "outputs": [ { @@ -264,7 +15026,7 @@ { "cell_type": "code", "execution_count": 94, - "id": "4e91263d-78ea-43d6-b09b-1e369377d115", + "id": "bdb8bf4d", "metadata": {}, "outputs": [ { @@ -297,7 +15059,7 @@ { "cell_type": "code", "execution_count": null, - "id": "5e36850a-3350-4535-a809-da36cdbf00ce", + "id": "feb41d2c", "metadata": {}, "outputs": [], "source": [] diff --git a/tessreduce/helpers.py b/tessreduce/helpers.py index b08d034..99634c4 100644 --- a/tessreduce/helpers.py +++ b/tessreduce/helpers.py @@ -17,12 +17,14 @@ 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 + from astropy.table import Table from astropy.stats import sigma_clipped_stats from astropy.stats import sigma_clip @@ -996,23 +998,45 @@ def regional_stats_mask(image,size=90,sigma=3,iters=10): return clip + +def subdivide_region(flux,ideal_size=90): + sx, sy = flux.shape + valid = np.arange(0,101) + ystep = valid[np.where(sy / valid == sy // valid)[0]] + xstep = valid[np.where(sx / valid == sx // valid)[0]] + + ysteps = ystep[np.argmin((abs((sy / ystep) - ideal_size)))].astype(int) + xsteps = xstep[np.argmin((abs((sx / xstep) - ideal_size)))].astype(int) + ystep = sy//ystep[np.argmin((abs((sy / ystep) - ideal_size)))].astype(int) + xstep = sx//xstep[np.argmin((abs((sx / xstep) - ideal_size)))].astype(int) + + regions = np.zeros_like(flux) + counter = 0 + for i in range(ysteps): + for j in range(xsteps): + regions[i*ystep:(i+1)*ystep,j*xstep:(j+1)*xstep] = counter + counter += 1 + + max_reg = np.max(regions) + return regions, max_reg, ystep, xstep + def Surface_names2model(names): # C[i] * X^n * Y^m return ' + '.join([ f"C[{i}]*{n.replace(' ','*')}" for i,n in enumerate(names)]) -def clip_background(bkg,mask,sigma=3): - regions, max_reg = subdivide_region(bkg) +def clip_background(bkg,mask,sigma=3,kern_size=5): + regions, max_reg, ystep, xstep = subdivide_region(bkg) b2 = deepcopy(bkg) for j in range(2): for region in range(int(max_reg)): - rx,ry = np.where(regions == region) - y = rx.reshape(ystep,xstep) - x = ry.reshape(ystep,xstep) + ry,rx = np.where(regions == region) + y = ry.reshape(ystep,xstep) + x = rx.reshape(ystep,xstep) sm = abs((mask & 1)-1)[y,x] * 1.0 sm[sm==0] = np.nan - cut = b2[i,y,x] + cut = b2[y,x] if j > 0: masked = cut * sm else: diff --git a/tessreduce/tessreduce.py b/tessreduce/tessreduce.py index 0144872..e76d74f 100644 --- a/tessreduce/tessreduce.py +++ b/tessreduce/tessreduce.py @@ -609,7 +609,7 @@ def _bkg_round_3(self,iters=5): bkg_3[i] = parallel_bkg3(self.bkg[i],dist_mask[i]) self.bkg = np.array(bkg_3) - def _clip_background(self,sigma=5): + def _clip_background(self,sigma=5,ideal_size=90): """ DESCRIPTION @@ -625,12 +625,12 @@ def _clip_background(self,sigma=5): """ if self.parallel: - bkg_clip = Parallel(n_jobs=self.num_cores)(delayed(clip_background)(self.bkg[i],self.mask,sigma) + 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))) else: bkg_clip = [] for i in range(len(dist_mask)): - bkg_clip[i] = clip_background(self.bkg[i],self.mask) + bkg_clip[i] = clip_background(self.bkg[i],self.mask,ideal_size) self.bkg = np.array(bkg_clip) def get_ref(self,start = None, stop = None):