From 38c91edbe1dd05dee1b6931959718fa584dcb65b Mon Sep 17 00:00:00 2001 From: SiggyF Date: Sun, 13 Apr 2025 16:02:02 +0200 Subject: [PATCH 1/2] cleanup and lint --- 2-analysis-examples/ship-cpa.ipynb | 2405 ++++++++++++++++++++++++++++ 1 file changed, 2405 insertions(+) create mode 100644 2-analysis-examples/ship-cpa.ipynb diff --git a/2-analysis-examples/ship-cpa.ipynb b/2-analysis-examples/ship-cpa.ipynb new file mode 100644 index 0000000..46634cd --- /dev/null +++ b/2-analysis-examples/ship-cpa.ipynb @@ -0,0 +1,2405 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "30f0a27a-919d-466f-9625-30d486ede07b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " const force = true;\n", + " const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n", + " const reloading = false;\n", + " const Bokeh = root.Bokeh;\n", + "\n", + " // Set a timeout for this load but only if we are not already initializing\n", + " if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks;\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + " if (js_modules == null) js_modules = [];\n", + " if (js_exports == null) js_exports = {};\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + "\n", + " if (root._bokeh_is_loading > 0) {\n", + " // Don't load bokeh if it is still initializing\n", + " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", + " return null;\n", + " } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n", + " // There is nothing to load\n", + " run_callbacks();\n", + " return null;\n", + " }\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + " window._bokeh_on_load = on_load\n", + "\n", + " function on_error(e) {\n", + " const src_el = e.srcElement\n", + " console.error(\"failed to load \" + (src_el.href || src_el.src));\n", + " }\n", + "\n", + " const skip = [];\n", + " if (window.requirejs) {\n", + " window.requirejs.config({'packages': {}, 'paths': {}, 'shim': {}});\n", + " root._bokeh_is_loading = css_urls.length + 0;\n", + " } else {\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n", + " }\n", + "\n", + " const existing_stylesheets = []\n", + " const links = document.getElementsByTagName('link')\n", + " for (let i = 0; i < links.length; i++) {\n", + " const link = links[i]\n", + " if (link.href != null) {\n", + " existing_stylesheets.push(link.href)\n", + " }\n", + " }\n", + " for (let i = 0; i < css_urls.length; i++) {\n", + " const url = css_urls[i];\n", + " const escaped = encodeURI(url)\n", + " if (existing_stylesheets.indexOf(escaped) !== -1) {\n", + " on_load()\n", + " continue;\n", + " }\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " } var existing_scripts = []\n", + " const scripts = document.getElementsByTagName('script')\n", + " for (let i = 0; i < scripts.length; i++) {\n", + " var script = scripts[i]\n", + " if (script.src != null) {\n", + " existing_scripts.push(script.src)\n", + " }\n", + " }\n", + " for (let i = 0; i < js_urls.length; i++) {\n", + " const url = js_urls[i];\n", + " const escaped = encodeURI(url)\n", + " if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n", + " if (!window.requirejs) {\n", + " on_load();\n", + " }\n", + " continue;\n", + " }\n", + " const element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " for (let i = 0; i < js_modules.length; i++) {\n", + " const url = js_modules[i];\n", + " const escaped = encodeURI(url)\n", + " if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n", + " if (!window.requirejs) {\n", + " on_load();\n", + " }\n", + " continue;\n", + " }\n", + " var element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.async = false;\n", + " element.src = url;\n", + " element.type = \"module\";\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " for (const name in js_exports) {\n", + " const url = js_exports[name];\n", + " const escaped = encodeURI(url)\n", + " if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n", + " if (!window.requirejs) {\n", + " on_load();\n", + " }\n", + " continue;\n", + " }\n", + " var element = document.createElement('script');\n", + " element.onerror = on_error;\n", + " element.async = false;\n", + " element.type = \"module\";\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " element.textContent = `\n", + " import ${name} from \"${url}\"\n", + " window.${name} = ${name}\n", + " window._bokeh_on_load()\n", + " `\n", + " document.head.appendChild(element);\n", + " }\n", + " if (!js_urls.length && !js_modules.length) {\n", + " on_load()\n", + " }\n", + " };\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " const js_urls = [\"https://cdn.holoviz.org/panel/1.5.3/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.2.min.js\", \"https://cdn.holoviz.org/panel/1.5.3/dist/panel.min.js\"];\n", + " const js_modules = [];\n", + " const js_exports = {};\n", + " const css_urls = [];\n", + " const inline_js = [ function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + "function(Bokeh) {} // ensure no trailing comma for IE\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " if ((root.Bokeh !== undefined) || (force === true)) {\n", + " for (let i = 0; i < inline_js.length; i++) {\n", + " try {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " } catch(e) {\n", + " if (!reloading) {\n", + " throw e;\n", + " }\n", + " }\n", + " }\n", + " // Cache old bokeh versions\n", + " if (Bokeh != undefined && !reloading) {\n", + " var NewBokeh = root.Bokeh;\n", + " if (Bokeh.versions === undefined) {\n", + " Bokeh.versions = new Map();\n", + " }\n", + " if (NewBokeh.version !== Bokeh.version) {\n", + " Bokeh.versions.set(NewBokeh.version, NewBokeh)\n", + " }\n", + " root.Bokeh = Bokeh;\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(run_inline_js, 100);\n", + " } else if (!root._bokeh_failed_load) {\n", + " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", + " root._bokeh_failed_load = true;\n", + " }\n", + " root._bokeh_is_initializing = false\n", + " }\n", + "\n", + " function load_or_wait() {\n", + " // Implement a backoff loop that tries to ensure we do not load multiple\n", + " // versions of Bokeh and its dependencies at the same time.\n", + " // In recent versions we use the root._bokeh_is_initializing flag\n", + " // to determine whether there is an ongoing attempt to initialize\n", + " // bokeh, however for backward compatibility we also try to ensure\n", + " // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n", + " // before older versions are fully initialized.\n", + " if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n", + " // If the timeout and bokeh was not successfully loaded we reset\n", + " // everything and try loading again\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_is_initializing = false;\n", + " root._bokeh_onload_callbacks = undefined;\n", + " root._bokeh_is_loading = 0\n", + " console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n", + " load_or_wait();\n", + " } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n", + " setTimeout(load_or_wait, 100);\n", + " } else {\n", + " root._bokeh_is_initializing = true\n", + " root._bokeh_onload_callbacks = []\n", + " const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n", + " if (!reloading && !bokeh_loaded) {\n", + " if (root.Bokeh) {\n", + " root.Bokeh = undefined;\n", + " }\n", + " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " }\n", + " load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + " }\n", + " // Give older versions of the autoload script a head-start to ensure\n", + " // they initialize before we start loading newer version.\n", + " setTimeout(load_or_wait, 100)\n", + "}(window));" + ], + "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n const reloading = false;\n const Bokeh = root.Bokeh;\n\n // Set a timeout for this load but only if we are not already initializing\n if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n // Don't load bokeh if it is still initializing\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n // There is nothing to load\n run_callbacks();\n return null;\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error(e) {\n const src_el = e.srcElement\n console.error(\"failed to load \" + (src_el.href || src_el.src));\n }\n\n const skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {}, 'shim': {}});\n root._bokeh_is_loading = css_urls.length + 0;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n const existing_stylesheets = []\n const links = document.getElementsByTagName('link')\n for (let i = 0; i < links.length; i++) {\n const link = links[i]\n if (link.href != null) {\n existing_stylesheets.push(link.href)\n }\n }\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const escaped = encodeURI(url)\n if (existing_stylesheets.indexOf(escaped) !== -1) {\n on_load()\n continue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } var existing_scripts = []\n const scripts = document.getElementsByTagName('script')\n for (let i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n existing_scripts.push(script.src)\n }\n }\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (let i = 0; i < js_modules.length; i++) {\n const url = js_modules[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n const url = js_exports[name];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.holoviz.org/panel/1.5.3/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.2.min.js\", \"https://cdn.holoviz.org/panel/1.5.3/dist/panel.min.js\"];\n const js_modules = [];\n const js_exports = {};\n const css_urls = [];\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (let i = 0; i < inline_js.length; i++) {\n try {\n inline_js[i].call(root, root.Bokeh);\n } catch(e) {\n if (!reloading) {\n throw e;\n }\n }\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n var NewBokeh = root.Bokeh;\n if (Bokeh.versions === undefined) {\n Bokeh.versions = new Map();\n }\n if (NewBokeh.version !== Bokeh.version) {\n Bokeh.versions.set(NewBokeh.version, NewBokeh)\n }\n root.Bokeh = Bokeh;\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n // If the timeout and bokeh was not successfully loaded we reset\n // everything and try loading again\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n root._bokeh_is_loading = 0\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n if (!reloading && !bokeh_loaded) {\n if (root.Bokeh) {\n root.Bokeh = undefined;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", + " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", + "}\n", + "\n", + "\n", + " function JupyterCommManager() {\n", + " }\n", + "\n", + " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", + " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", + " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", + " comm_manager.register_target(comm_id, function(comm) {\n", + " comm.on_msg(msg_handler);\n", + " });\n", + " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", + " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", + " comm.onMsg = msg_handler;\n", + " });\n", + " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", + " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", + " var messages = comm.messages[Symbol.asyncIterator]();\n", + " function processIteratorResult(result) {\n", + " var message = result.value;\n", + " console.log(message)\n", + " var content = {data: message.data, comm_id};\n", + " var buffers = []\n", + " for (var buffer of message.buffers || []) {\n", + " buffers.push(new DataView(buffer))\n", + " }\n", + " var metadata = message.metadata || {};\n", + " var msg = {content, buffers, metadata}\n", + " msg_handler(msg);\n", + " return messages.next().then(processIteratorResult);\n", + " }\n", + " return messages.next().then(processIteratorResult);\n", + " })\n", + " }\n", + " }\n", + "\n", + " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", + " if (comm_id in window.PyViz.comms) {\n", + " return window.PyViz.comms[comm_id];\n", + " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", + " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", + " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", + " if (msg_handler) {\n", + " comm.on_msg(msg_handler);\n", + " }\n", + " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", + " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", + " comm.open();\n", + " if (msg_handler) {\n", + " comm.onMsg = msg_handler;\n", + " }\n", + " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", + " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", + " comm_promise.then((comm) => {\n", + " window.PyViz.comms[comm_id] = comm;\n", + " if (msg_handler) {\n", + " var messages = comm.messages[Symbol.asyncIterator]();\n", + " function processIteratorResult(result) {\n", + " var message = result.value;\n", + " var content = {data: message.data};\n", + " var metadata = message.metadata || {comm_id};\n", + " var msg = {content, metadata}\n", + " msg_handler(msg);\n", + " return messages.next().then(processIteratorResult);\n", + " }\n", + " return messages.next().then(processIteratorResult);\n", + " }\n", + " }) \n", + " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", + " return comm_promise.then((comm) => {\n", + " comm.send(data, metadata, buffers, disposeOnDone);\n", + " });\n", + " };\n", + " var comm = {\n", + " send: sendClosure\n", + " };\n", + " }\n", + " window.PyViz.comms[comm_id] = comm;\n", + " return comm;\n", + " }\n", + " window.PyViz.comm_manager = new JupyterCommManager();\n", + " \n", + "\n", + "\n", + "var JS_MIME_TYPE = 'application/javascript';\n", + "var HTML_MIME_TYPE = 'text/html';\n", + "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", + "var CLASS_NAME = 'output';\n", + "\n", + "/**\n", + " * Render data to the DOM node\n", + " */\n", + "function render(props, node) {\n", + " var div = document.createElement(\"div\");\n", + " var script = document.createElement(\"script\");\n", + " node.appendChild(div);\n", + " node.appendChild(script);\n", + "}\n", + "\n", + "/**\n", + " * Handle when a new output is added\n", + " */\n", + "function handle_add_output(event, handle) {\n", + " var output_area = handle.output_area;\n", + " var output = handle.output;\n", + " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", + " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", + " if (id !== undefined) {\n", + " var nchildren = toinsert.length;\n", + " var html_node = toinsert[nchildren-1].children[0];\n", + " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", + " var scripts = [];\n", + " var nodelist = html_node.querySelectorAll(\"script\");\n", + " for (var i in nodelist) {\n", + " if (nodelist.hasOwnProperty(i)) {\n", + " scripts.push(nodelist[i])\n", + " }\n", + " }\n", + "\n", + " scripts.forEach( function (oldScript) {\n", + " var newScript = document.createElement(\"script\");\n", + " var attrs = [];\n", + " var nodemap = oldScript.attributes;\n", + " for (var j in nodemap) {\n", + " if (nodemap.hasOwnProperty(j)) {\n", + " attrs.push(nodemap[j])\n", + " }\n", + " }\n", + " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", + " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", + " oldScript.parentNode.replaceChild(newScript, oldScript);\n", + " });\n", + " if (JS_MIME_TYPE in output.data) {\n", + " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", + " }\n", + " output_area._hv_plot_id = id;\n", + " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", + " window.PyViz.plot_index[id] = Bokeh.index[id];\n", + " } else {\n", + " window.PyViz.plot_index[id] = null;\n", + " }\n", + " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", + " var bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " var script_attrs = bk_div.children[0].attributes;\n", + " for (var i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " }\n", + " // store reference to server id on output_area\n", + " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", + " }\n", + "}\n", + "\n", + "/**\n", + " * Handle when an output is cleared or removed\n", + " */\n", + "function handle_clear_output(event, handle) {\n", + " var id = handle.cell.output_area._hv_plot_id;\n", + " var server_id = handle.cell.output_area._bokeh_server_id;\n", + " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", + " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", + " if (server_id !== null) {\n", + " comm.send({event_type: 'server_delete', 'id': server_id});\n", + " return;\n", + " } else if (comm !== null) {\n", + " comm.send({event_type: 'delete', 'id': id});\n", + " }\n", + " delete PyViz.plot_index[id];\n", + " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", + " var doc = window.Bokeh.index[id].model.document\n", + " doc.clear();\n", + " const i = window.Bokeh.documents.indexOf(doc);\n", + " if (i > -1) {\n", + " window.Bokeh.documents.splice(i, 1);\n", + " }\n", + " }\n", + "}\n", + "\n", + "/**\n", + " * Handle kernel restart event\n", + " */\n", + "function handle_kernel_cleanup(event, handle) {\n", + " delete PyViz.comms[\"hv-extension-comm\"];\n", + " window.PyViz.plot_index = {}\n", + "}\n", + "\n", + "/**\n", + " * Handle update_display_data messages\n", + " */\n", + "function handle_update_output(event, handle) {\n", + " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", + " handle_add_output(event, handle)\n", + "}\n", + "\n", + "function register_renderer(events, OutputArea) {\n", + " function append_mime(data, metadata, element) {\n", + " // create a DOM node to render to\n", + " var toinsert = this.create_output_subarea(\n", + " metadata,\n", + " CLASS_NAME,\n", + " EXEC_MIME_TYPE\n", + " );\n", + " this.keyboard_manager.register_events(toinsert);\n", + " // Render to node\n", + " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", + " render(props, toinsert[0]);\n", + " element.append(toinsert);\n", + " return toinsert\n", + " }\n", + "\n", + " events.on('output_added.OutputArea', handle_add_output);\n", + " events.on('output_updated.OutputArea', handle_update_output);\n", + " events.on('clear_output.CodeCell', handle_clear_output);\n", + " events.on('delete.Cell', handle_clear_output);\n", + " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", + "\n", + " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", + " safe: true,\n", + " index: 0\n", + " });\n", + "}\n", + "\n", + "if (window.Jupyter !== undefined) {\n", + " try {\n", + " var events = require('base/js/events');\n", + " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", + " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", + " register_renderer(events, OutputArea);\n", + " }\n", + " } catch(err) {\n", + " }\n", + "}\n" + ], + "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.holoviews_exec.v0+json": "", + "text/html": [ + "
\n", + "
\n", + "
\n", + "" + ] + }, + "metadata": { + "application/vnd.holoviews_exec.v0+json": { + "id": "p1002" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "import datetime\n", + "from typing import Iterator\n", + "\n", + "import folium\n", + "import geopandas as gpd\n", + "import hvplot.pandas\n", + "import matplotlib.colors\n", + "import matplotlib.pyplot as plt\n", + "import movingpandas as mpd\n", + "import movingpandas.cpa\n", + "import numpy as np\n", + "import pandas as pd\n", + "import shapely\n", + "from tqdm.notebook import tqdm" + ] + }, + { + "cell_type": "markdown", + "id": "460a21ed-9bee-4e8a-a862-b8cb443e9cf3", + "metadata": {}, + "source": [ + "# Closest point of approach example\n", + "This notebook demonstrates the CPA calculation for two trajectories. In maritime navigation, CPA stands for Closest Point of Approach. It is a concept used to assess the risk of collision between vessels. CPA refers to the minimum distance that will occur between two ships if they continue on their current courses and speeds. It is often calculated using data from the Automatic Identification System (AIS), which tracks vessel movements. Here the public Danish AIS dataset is used. \n", + "\n", + "There is an example where two ships meet on the evening of july 5th of 2017. The ships that approach eachother are MMSI: 265550210 and MMSI: 265410000. " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "7753cbbe-08e2-4f91-87f3-141bfccebeeb", + "metadata": {}, + "outputs": [], + "source": [ + "mmsi_a = 265550210\n", + "mmsi_b = 265410000\n", + "\n", + "color_a = (0, 0.3, 0.3)\n", + "color_b = (0.3, 0, 0.3)\n", + "t_0 = datetime.datetime(2017, 7, 5, 19, 0, 0)\n", + "t_1 = datetime.datetime(2017, 7, 5, 19, 13, 55)\n", + "\n", + "\n", + "# we expect to find this as the closest point and interval of overlapping time window\n", + "expected = {\n", + " \"t\": datetime.datetime(2017, 7, 5, 19, 8, 31),\n", + " \"p\": shapely.Point(669670.780244901, 6397464.37325368),\n", + " \"q\": shapely.Point(669566.587642144, 6397098.724455765),\n", + " \"t0_min\": datetime.datetime(2017, 7, 5, 19, 0, 1),\n", + " \"t1_max\": datetime.datetime(2017, 7, 5, 19, 13, 53),\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "db13d8d3-9e00-4206-9568-f3f060274b9b", + "metadata": {}, + "source": [ + "# Read the data\n", + "Here we read the data from a geopackage file. We convert the timestamps to a real date object. \n", + "For visualisation purposes we add a variable `t_min_t_0` so that we can visualize the time since start of the trajectories. \n", + "We convert the data to UTM 32N so that we can do our computations in Euclidean space, in meters.\n", + "\n", + "We'll subset the data using the 2 ship identifiers and our time window of interest. " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "baa1b901-c744-43fc-9dfe-4f98853636d3", + "metadata": {}, + "outputs": [], + "source": [ + "ais_gdf = gpd.read_file(\"../data/ais.gpkg\")\n", + "ais_gdf[\"t\"] = pd.to_datetime(ais_gdf[\"Timestamp\"], format=\"%d/%m/%Y %H:%M:%S\")\n", + "ais_gdf[\"t_min_t_0\"] = (ais_gdf[\"t\"] - t_0).dt.total_seconds()\n", + "\n", + "# convert to local UTM so we can do metric calculations\n", + "ais_gdf = ais_gdf.to_crs(\"EPSG:32632\")\n", + "ais_gdf = ais_gdf.sort_values([\"MMSI\", \"t\"])" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "f2c4b3cb-36c1-44f3-8770-2ba267354df3", + "metadata": {}, + "outputs": [], + "source": [ + "# Filter on MMSI of interest and time window of interest\n", + "ais_gdf = ais_gdf[\n", + " np.logical_and.reduce(\n", + " [\n", + " ais_gdf[\"MMSI\"].isin([mmsi_a, mmsi_b]),\n", + " ais_gdf[\"t\"] >= t_0,\n", + " ais_gdf[\"t\"] < t_1,\n", + " ]\n", + " )\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "7fb044db-4631-4718-a046-c9d1ce6c8bf8", + "metadata": {}, + "source": [ + "# Convert to trajectories\n", + "Here we convert our data into trajectories. We'll extract the 2 trajectories as seperate trajectories. \n", + "The CPA calculation uses a pair of trajectories as input. " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "6be51834-5ee6-447f-ba79-804f174f501a", + "metadata": {}, + "outputs": [], + "source": [ + "ais_gdf[\"traj_id\"] = ais_gdf[\"MMSI\"]\n", + "ais_gdf[\"obj_id\"] = ais_gdf[\"MMSI\"]\n", + "traj_collection = mpd.TrajectoryCollection(\n", + " ais_gdf.set_index(\"t\"), traj_id_col=\"traj_id\", obj_id_col=\"obj_id\", min_length=100\n", + ")\n", + "traj_collection.add_speed(overwrite=True, units=(\"m\", \"s\"))\n", + "traj_collection.add_direction(overwrite=True)\n", + "\n", + "\n", + "traj_a = traj_collection.get_trajectory(mmsi_a)\n", + "traj_b = traj_collection.get_trajectory(mmsi_b)" + ] + }, + { + "cell_type": "markdown", + "id": "f34c1260-b1df-4c4d-a08a-a3b3a4210e4e", + "metadata": {}, + "source": [ + "# Visualisation\n", + "We'll create a visualization using the `hvplot` code from holoviews. This shows that the trajectories overlapped. \n", + "But how close did the ships get to eachother? That is what we'll compute here. " + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "e4a69b49-c978-49a3-a30b-4c07eada1d1f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " const force = true;\n", + " const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n", + " const reloading = false;\n", + " const Bokeh = root.Bokeh;\n", + "\n", + " // Set a timeout for this load but only if we are not already initializing\n", + " if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks;\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + " if (js_modules == null) js_modules = [];\n", + " if (js_exports == null) js_exports = {};\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + "\n", + " if (root._bokeh_is_loading > 0) {\n", + " // Don't load bokeh if it is still initializing\n", + " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", + " return null;\n", + " } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n", + " // There is nothing to load\n", + " run_callbacks();\n", + " return null;\n", + " }\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + " window._bokeh_on_load = on_load\n", + "\n", + " function on_error(e) {\n", + " const src_el = e.srcElement\n", + " console.error(\"failed to load \" + (src_el.href || src_el.src));\n", + " }\n", + "\n", + " const skip = [];\n", + " if (window.requirejs) {\n", + " window.requirejs.config({'packages': {}, 'paths': {}, 'shim': {}});\n", + " root._bokeh_is_loading = css_urls.length + 0;\n", + " } else {\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n", + " }\n", + "\n", + " const existing_stylesheets = []\n", + " const links = document.getElementsByTagName('link')\n", + " for (let i = 0; i < links.length; i++) {\n", + " const link = links[i]\n", + " if (link.href != null) {\n", + " existing_stylesheets.push(link.href)\n", + " }\n", + " }\n", + " for (let i = 0; i < css_urls.length; i++) {\n", + " const url = css_urls[i];\n", + " const escaped = encodeURI(url)\n", + " if (existing_stylesheets.indexOf(escaped) !== -1) {\n", + " on_load()\n", + " continue;\n", + " }\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " } var existing_scripts = []\n", + " const scripts = document.getElementsByTagName('script')\n", + " for (let i = 0; i < scripts.length; i++) {\n", + " var script = scripts[i]\n", + " if (script.src != null) {\n", + " existing_scripts.push(script.src)\n", + " }\n", + " }\n", + " for (let i = 0; i < js_urls.length; i++) {\n", + " const url = js_urls[i];\n", + " const escaped = encodeURI(url)\n", + " if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n", + " if (!window.requirejs) {\n", + " on_load();\n", + " }\n", + " continue;\n", + " }\n", + " const element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " for (let i = 0; i < js_modules.length; i++) {\n", + " const url = js_modules[i];\n", + " const escaped = encodeURI(url)\n", + " if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n", + " if (!window.requirejs) {\n", + " on_load();\n", + " }\n", + " continue;\n", + " }\n", + " var element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.async = false;\n", + " element.src = url;\n", + " element.type = \"module\";\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " for (const name in js_exports) {\n", + " const url = js_exports[name];\n", + " const escaped = encodeURI(url)\n", + " if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n", + " if (!window.requirejs) {\n", + " on_load();\n", + " }\n", + " continue;\n", + " }\n", + " var element = document.createElement('script');\n", + " element.onerror = on_error;\n", + " element.async = false;\n", + " element.type = \"module\";\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " element.textContent = `\n", + " import ${name} from \"${url}\"\n", + " window.${name} = ${name}\n", + " window._bokeh_on_load()\n", + " `\n", + " document.head.appendChild(element);\n", + " }\n", + " if (!js_urls.length && !js_modules.length) {\n", + " on_load()\n", + " }\n", + " };\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " const js_urls = [\"https://cdn.holoviz.org/panel/1.5.3/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.2.min.js\", \"https://cdn.holoviz.org/panel/1.5.3/dist/panel.min.js\"];\n", + " const js_modules = [];\n", + " const js_exports = {};\n", + " const css_urls = [];\n", + " const inline_js = [ function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + "function(Bokeh) {} // ensure no trailing comma for IE\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " if ((root.Bokeh !== undefined) || (force === true)) {\n", + " for (let i = 0; i < inline_js.length; i++) {\n", + " try {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " } catch(e) {\n", + " if (!reloading) {\n", + " throw e;\n", + " }\n", + " }\n", + " }\n", + " // Cache old bokeh versions\n", + " if (Bokeh != undefined && !reloading) {\n", + " var NewBokeh = root.Bokeh;\n", + " if (Bokeh.versions === undefined) {\n", + " Bokeh.versions = new Map();\n", + " }\n", + " if (NewBokeh.version !== Bokeh.version) {\n", + " Bokeh.versions.set(NewBokeh.version, NewBokeh)\n", + " }\n", + " root.Bokeh = Bokeh;\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(run_inline_js, 100);\n", + " } else if (!root._bokeh_failed_load) {\n", + " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", + " root._bokeh_failed_load = true;\n", + " }\n", + " root._bokeh_is_initializing = false\n", + " }\n", + "\n", + " function load_or_wait() {\n", + " // Implement a backoff loop that tries to ensure we do not load multiple\n", + " // versions of Bokeh and its dependencies at the same time.\n", + " // In recent versions we use the root._bokeh_is_initializing flag\n", + " // to determine whether there is an ongoing attempt to initialize\n", + " // bokeh, however for backward compatibility we also try to ensure\n", + " // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n", + " // before older versions are fully initialized.\n", + " if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n", + " // If the timeout and bokeh was not successfully loaded we reset\n", + " // everything and try loading again\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_is_initializing = false;\n", + " root._bokeh_onload_callbacks = undefined;\n", + " root._bokeh_is_loading = 0\n", + " console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n", + " load_or_wait();\n", + " } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n", + " setTimeout(load_or_wait, 100);\n", + " } else {\n", + " root._bokeh_is_initializing = true\n", + " root._bokeh_onload_callbacks = []\n", + " const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n", + " if (!reloading && !bokeh_loaded) {\n", + " if (root.Bokeh) {\n", + " root.Bokeh = undefined;\n", + " }\n", + " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " }\n", + " load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + " }\n", + " // Give older versions of the autoload script a head-start to ensure\n", + " // they initialize before we start loading newer version.\n", + " setTimeout(load_or_wait, 100)\n", + "}(window));" + ], + "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n const reloading = false;\n const Bokeh = root.Bokeh;\n\n // Set a timeout for this load but only if we are not already initializing\n if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n // Don't load bokeh if it is still initializing\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n // There is nothing to load\n run_callbacks();\n return null;\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error(e) {\n const src_el = e.srcElement\n console.error(\"failed to load \" + (src_el.href || src_el.src));\n }\n\n const skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {}, 'shim': {}});\n root._bokeh_is_loading = css_urls.length + 0;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n const existing_stylesheets = []\n const links = document.getElementsByTagName('link')\n for (let i = 0; i < links.length; i++) {\n const link = links[i]\n if (link.href != null) {\n existing_stylesheets.push(link.href)\n }\n }\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const escaped = encodeURI(url)\n if (existing_stylesheets.indexOf(escaped) !== -1) {\n on_load()\n continue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } var existing_scripts = []\n const scripts = document.getElementsByTagName('script')\n for (let i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n existing_scripts.push(script.src)\n }\n }\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (let i = 0; i < js_modules.length; i++) {\n const url = js_modules[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n const url = js_exports[name];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.holoviz.org/panel/1.5.3/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.2.min.js\", \"https://cdn.holoviz.org/panel/1.5.3/dist/panel.min.js\"];\n const js_modules = [];\n const js_exports = {};\n const css_urls = [];\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (let i = 0; i < inline_js.length; i++) {\n try {\n inline_js[i].call(root, root.Bokeh);\n } catch(e) {\n if (!reloading) {\n throw e;\n }\n }\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n var NewBokeh = root.Bokeh;\n if (Bokeh.versions === undefined) {\n Bokeh.versions = new Map();\n }\n if (NewBokeh.version !== Bokeh.version) {\n Bokeh.versions.set(NewBokeh.version, NewBokeh)\n }\n root.Bokeh = Bokeh;\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n // If the timeout and bokeh was not successfully loaded we reset\n // everything and try loading again\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n root._bokeh_is_loading = 0\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n if (!reloading && !bokeh_loaded) {\n if (root.Bokeh) {\n root.Bokeh = undefined;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", + " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", + "}\n", + "\n", + "\n", + " function JupyterCommManager() {\n", + " }\n", + "\n", + " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", + " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", + " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", + " comm_manager.register_target(comm_id, function(comm) {\n", + " comm.on_msg(msg_handler);\n", + " });\n", + " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", + " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", + " comm.onMsg = msg_handler;\n", + " });\n", + " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", + " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", + " var messages = comm.messages[Symbol.asyncIterator]();\n", + " function processIteratorResult(result) {\n", + " var message = result.value;\n", + " console.log(message)\n", + " var content = {data: message.data, comm_id};\n", + " var buffers = []\n", + " for (var buffer of message.buffers || []) {\n", + " buffers.push(new DataView(buffer))\n", + " }\n", + " var metadata = message.metadata || {};\n", + " var msg = {content, buffers, metadata}\n", + " msg_handler(msg);\n", + " return messages.next().then(processIteratorResult);\n", + " }\n", + " return messages.next().then(processIteratorResult);\n", + " })\n", + " }\n", + " }\n", + "\n", + " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", + " if (comm_id in window.PyViz.comms) {\n", + " return window.PyViz.comms[comm_id];\n", + " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", + " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", + " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", + " if (msg_handler) {\n", + " comm.on_msg(msg_handler);\n", + " }\n", + " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", + " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", + " comm.open();\n", + " if (msg_handler) {\n", + " comm.onMsg = msg_handler;\n", + " }\n", + " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", + " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", + " comm_promise.then((comm) => {\n", + " window.PyViz.comms[comm_id] = comm;\n", + " if (msg_handler) {\n", + " var messages = comm.messages[Symbol.asyncIterator]();\n", + " function processIteratorResult(result) {\n", + " var message = result.value;\n", + " var content = {data: message.data};\n", + " var metadata = message.metadata || {comm_id};\n", + " var msg = {content, metadata}\n", + " msg_handler(msg);\n", + " return messages.next().then(processIteratorResult);\n", + " }\n", + " return messages.next().then(processIteratorResult);\n", + " }\n", + " }) \n", + " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", + " return comm_promise.then((comm) => {\n", + " comm.send(data, metadata, buffers, disposeOnDone);\n", + " });\n", + " };\n", + " var comm = {\n", + " send: sendClosure\n", + " };\n", + " }\n", + " window.PyViz.comms[comm_id] = comm;\n", + " return comm;\n", + " }\n", + " window.PyViz.comm_manager = new JupyterCommManager();\n", + " \n", + "\n", + "\n", + "var JS_MIME_TYPE = 'application/javascript';\n", + "var HTML_MIME_TYPE = 'text/html';\n", + "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", + "var CLASS_NAME = 'output';\n", + "\n", + "/**\n", + " * Render data to the DOM node\n", + " */\n", + "function render(props, node) {\n", + " var div = document.createElement(\"div\");\n", + " var script = document.createElement(\"script\");\n", + " node.appendChild(div);\n", + " node.appendChild(script);\n", + "}\n", + "\n", + "/**\n", + " * Handle when a new output is added\n", + " */\n", + "function handle_add_output(event, handle) {\n", + " var output_area = handle.output_area;\n", + " var output = handle.output;\n", + " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", + " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", + " if (id !== undefined) {\n", + " var nchildren = toinsert.length;\n", + " var html_node = toinsert[nchildren-1].children[0];\n", + " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", + " var scripts = [];\n", + " var nodelist = html_node.querySelectorAll(\"script\");\n", + " for (var i in nodelist) {\n", + " if (nodelist.hasOwnProperty(i)) {\n", + " scripts.push(nodelist[i])\n", + " }\n", + " }\n", + "\n", + " scripts.forEach( function (oldScript) {\n", + " var newScript = document.createElement(\"script\");\n", + " var attrs = [];\n", + " var nodemap = oldScript.attributes;\n", + " for (var j in nodemap) {\n", + " if (nodemap.hasOwnProperty(j)) {\n", + " attrs.push(nodemap[j])\n", + " }\n", + " }\n", + " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", + " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", + " oldScript.parentNode.replaceChild(newScript, oldScript);\n", + " });\n", + " if (JS_MIME_TYPE in output.data) {\n", + " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", + " }\n", + " output_area._hv_plot_id = id;\n", + " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", + " window.PyViz.plot_index[id] = Bokeh.index[id];\n", + " } else {\n", + " window.PyViz.plot_index[id] = null;\n", + " }\n", + " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", + " var bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " var script_attrs = bk_div.children[0].attributes;\n", + " for (var i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " }\n", + " // store reference to server id on output_area\n", + " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", + " }\n", + "}\n", + "\n", + "/**\n", + " * Handle when an output is cleared or removed\n", + " */\n", + "function handle_clear_output(event, handle) {\n", + " var id = handle.cell.output_area._hv_plot_id;\n", + " var server_id = handle.cell.output_area._bokeh_server_id;\n", + " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", + " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", + " if (server_id !== null) {\n", + " comm.send({event_type: 'server_delete', 'id': server_id});\n", + " return;\n", + " } else if (comm !== null) {\n", + " comm.send({event_type: 'delete', 'id': id});\n", + " }\n", + " delete PyViz.plot_index[id];\n", + " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", + " var doc = window.Bokeh.index[id].model.document\n", + " doc.clear();\n", + " const i = window.Bokeh.documents.indexOf(doc);\n", + " if (i > -1) {\n", + " window.Bokeh.documents.splice(i, 1);\n", + " }\n", + " }\n", + "}\n", + "\n", + "/**\n", + " * Handle kernel restart event\n", + " */\n", + "function handle_kernel_cleanup(event, handle) {\n", + " delete PyViz.comms[\"hv-extension-comm\"];\n", + " window.PyViz.plot_index = {}\n", + "}\n", + "\n", + "/**\n", + " * Handle update_display_data messages\n", + " */\n", + "function handle_update_output(event, handle) {\n", + " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", + " handle_add_output(event, handle)\n", + "}\n", + "\n", + "function register_renderer(events, OutputArea) {\n", + " function append_mime(data, metadata, element) {\n", + " // create a DOM node to render to\n", + " var toinsert = this.create_output_subarea(\n", + " metadata,\n", + " CLASS_NAME,\n", + " EXEC_MIME_TYPE\n", + " );\n", + " this.keyboard_manager.register_events(toinsert);\n", + " // Render to node\n", + " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", + " render(props, toinsert[0]);\n", + " element.append(toinsert);\n", + " return toinsert\n", + " }\n", + "\n", + " events.on('output_added.OutputArea', handle_add_output);\n", + " events.on('output_updated.OutputArea', handle_update_output);\n", + " events.on('clear_output.CodeCell', handle_clear_output);\n", + " events.on('delete.Cell', handle_clear_output);\n", + " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", + "\n", + " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", + " safe: true,\n", + " index: 0\n", + " });\n", + "}\n", + "\n", + "if (window.Jupyter !== undefined) {\n", + " try {\n", + " var events = require('base/js/events');\n", + " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", + " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", + " register_renderer(events, OutputArea);\n", + " }\n", + " } catch(err) {\n", + " }\n", + "}\n" + ], + "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.holoviews_exec.v0+json": "", + "text/html": [ + "
\n", + "
\n", + "
\n", + "" + ] + }, + "metadata": { + "application/vnd.holoviews_exec.v0+json": { + "id": "p1004" + } + }, + "output_type": "display_data" + }, + { + "data": {}, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.holoviews_exec.v0+json": "", + "text/html": [ + "
\n", + "
\n", + "
\n", + "" + ], + "text/plain": [ + ":Overlay\n", + " .WMTS.I :WMTS [Longitude,Latitude]\n", + " .Path.I :Path [Longitude,Latitude] (t_min_t_0)\n", + " .Points.I :Points [Longitude,Latitude] (t_min_t_0,triangle_angle)" + ] + }, + "execution_count": 6, + "metadata": { + "application/vnd.holoviews_exec.v0+json": { + "id": "p1015" + } + }, + "output_type": "execute_result" + } + ], + "source": [ + "# create a variant in wgs84 to show a plot\n", + "traj_collection_wgs84 = mpd.TrajectoryCollection(\n", + " ais_gdf.to_crs(\"EPSG:4326\").set_index(\"t\"),\n", + " traj_id_col=\"traj_id\",\n", + " obj_id_col=\"obj_id\",\n", + " min_length=100,\n", + ")\n", + "# show trajectories with number of seconds since t_0\n", + "traj_collection_wgs84.hvplot(c=\"t_min_t_0\", cmap=\"Blues\")" + ] + }, + { + "cell_type": "markdown", + "id": "76c90f0e-1451-47bf-b237-85dfd874f38e", + "metadata": {}, + "source": [ + "# Calculate the CPA\n", + "Now we have the functions defined we can compute a dataframe of all the cpa calculations for each sequential time step pair in the timesteps of ship a and b. The table has a lot of variables that we'll probably remove. We'll probably keep the position of the closest point (actualy a line, pq), the distance (dist) and the time (t) and maybe the status or a code. " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "5075ff5d-9222-4b49-814b-c436b9c7821c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
t_att_togeometrydiststatus
1302017-07-05 19:08:31.8926602260.654740LINESTRING (669670.78 6397464.373, 669566.588 ...380.204079approaching
1312017-07-05 19:08:35.000000000-3.393321LINESTRING (669676.948 6397452.972, 669547.789...381.089295diverging
1292017-07-05 19:08:25.000000000-22.385399LINESTRING (669659.084 6397485.995, 669608.109...381.202006diverging
1282017-07-05 19:08:25.0000000001.933643LINESTRING (669659.084 6397485.995, 669608.109...381.202006converging
1322017-07-05 19:08:36.000000000-0.540582LINESTRING (669678.62 6397449.419, 669541.74 6...381.746013diverging
\n", + "
" + ], + "text/plain": [ + " t_at t_to \\\n", + "130 2017-07-05 19:08:31.892660226 0.654740 \n", + "131 2017-07-05 19:08:35.000000000 -3.393321 \n", + "129 2017-07-05 19:08:25.000000000 -22.385399 \n", + "128 2017-07-05 19:08:25.000000000 1.933643 \n", + "132 2017-07-05 19:08:36.000000000 -0.540582 \n", + "\n", + " geometry dist \\\n", + "130 LINESTRING (669670.78 6397464.373, 669566.588 ... 380.204079 \n", + "131 LINESTRING (669676.948 6397452.972, 669547.789... 381.089295 \n", + "129 LINESTRING (669659.084 6397485.995, 669608.109... 381.202006 \n", + "128 LINESTRING (669659.084 6397485.995, 669608.109... 381.202006 \n", + "132 LINESTRING (669678.62 6397449.419, 669541.74 6... 381.746013 \n", + "\n", + " status \n", + "130 approaching \n", + "131 diverging \n", + "129 diverging \n", + "128 converging \n", + "132 diverging " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cpa_calc = movingpandas.cpa.CPACalculator(traj_a, traj_b)\n", + "cpa_df = cpa_calc.segments_gdf()\n", + "cpa = cpa_calc.min()\n", + "cpa_df.sort_values(\"dist\").head()" + ] + }, + { + "cell_type": "markdown", + "id": "bdaed393-b497-49b1-92a9-a76bc943e659", + "metadata": {}, + "source": [ + "# Visualisation\n", + "This visualization shows what has been computed. All the blue lines show the segments for which a CPA has been computed. \n", + "Between these sets a red line was found (using interpolation) where the ships were closest to eachother (assuming their current course, so not just in distance). This red line is what is referred to as the Closest Point of Approach. The distance was 380m and the time of this CPA was 2017-07-05 19:08:31. We'll also visualize the line of closest point of approach using a holoviews map." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "8027c913-1bdd-4f3b-b2d0-9d4e97b9d24b", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "\n", + "ax.set_xlabel(\"x [m, UTM32N]\")\n", + "ax.set_ylabel(\"y [m, UTM32N]\")\n", + "ax.set_title(\n", + " f\"Closest point of approach\\ndistance: {cpa.dist:.0f}m\\nMMSI: {mmsi_a} & {mmsi_b}\\n{cpa.t_at}\"\n", + ")\n", + "\n", + "# compute colors ranging from\n", + "N = matplotlib.colors.Normalize(0, cpa_df[\"dist\"].max())\n", + "cmap = matplotlib.cm.RdYlGn\n", + "colors = cmap(N(cpa_df[\"dist\"]))\n", + "thin = 15\n", + "# don't show all the computed lines\n", + "cpa_df[::thin].plot(ax=ax, color=colors[::thin])\n", + "# show the computed closest point of approach\n", + "gpd.GeoSeries(cpa[\"geometry\"]).plot(ax=ax, color=\"black\", linestyle=\":\")\n", + "traj_a.plot(ax=ax)\n", + "traj_b.plot(ax=ax);" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "79146a33-d758-4c5e-a9dc-b2df5d5f5c5b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " const force = true;\n", + " const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n", + " const reloading = false;\n", + " const Bokeh = root.Bokeh;\n", + "\n", + " // Set a timeout for this load but only if we are not already initializing\n", + " if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks;\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + " if (js_modules == null) js_modules = [];\n", + " if (js_exports == null) js_exports = {};\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + "\n", + " if (root._bokeh_is_loading > 0) {\n", + " // Don't load bokeh if it is still initializing\n", + " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", + " return null;\n", + " } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n", + " // There is nothing to load\n", + " run_callbacks();\n", + " return null;\n", + " }\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + " window._bokeh_on_load = on_load\n", + "\n", + " function on_error(e) {\n", + " const src_el = e.srcElement\n", + " console.error(\"failed to load \" + (src_el.href || src_el.src));\n", + " }\n", + "\n", + " const skip = [];\n", + " if (window.requirejs) {\n", + " window.requirejs.config({'packages': {}, 'paths': {}, 'shim': {}});\n", + " root._bokeh_is_loading = css_urls.length + 0;\n", + " } else {\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n", + " }\n", + "\n", + " const existing_stylesheets = []\n", + " const links = document.getElementsByTagName('link')\n", + " for (let i = 0; i < links.length; i++) {\n", + " const link = links[i]\n", + " if (link.href != null) {\n", + " existing_stylesheets.push(link.href)\n", + " }\n", + " }\n", + " for (let i = 0; i < css_urls.length; i++) {\n", + " const url = css_urls[i];\n", + " const escaped = encodeURI(url)\n", + " if (existing_stylesheets.indexOf(escaped) !== -1) {\n", + " on_load()\n", + " continue;\n", + " }\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " } var existing_scripts = []\n", + " const scripts = document.getElementsByTagName('script')\n", + " for (let i = 0; i < scripts.length; i++) {\n", + " var script = scripts[i]\n", + " if (script.src != null) {\n", + " existing_scripts.push(script.src)\n", + " }\n", + " }\n", + " for (let i = 0; i < js_urls.length; i++) {\n", + " const url = js_urls[i];\n", + " const escaped = encodeURI(url)\n", + " if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n", + " if (!window.requirejs) {\n", + " on_load();\n", + " }\n", + " continue;\n", + " }\n", + " const element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " for (let i = 0; i < js_modules.length; i++) {\n", + " const url = js_modules[i];\n", + " const escaped = encodeURI(url)\n", + " if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n", + " if (!window.requirejs) {\n", + " on_load();\n", + " }\n", + " continue;\n", + " }\n", + " var element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.async = false;\n", + " element.src = url;\n", + " element.type = \"module\";\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " for (const name in js_exports) {\n", + " const url = js_exports[name];\n", + " const escaped = encodeURI(url)\n", + " if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n", + " if (!window.requirejs) {\n", + " on_load();\n", + " }\n", + " continue;\n", + " }\n", + " var element = document.createElement('script');\n", + " element.onerror = on_error;\n", + " element.async = false;\n", + " element.type = \"module\";\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " element.textContent = `\n", + " import ${name} from \"${url}\"\n", + " window.${name} = ${name}\n", + " window._bokeh_on_load()\n", + " `\n", + " document.head.appendChild(element);\n", + " }\n", + " if (!js_urls.length && !js_modules.length) {\n", + " on_load()\n", + " }\n", + " };\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " const js_urls = [\"https://cdn.holoviz.org/panel/1.5.3/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.2.min.js\", \"https://cdn.holoviz.org/panel/1.5.3/dist/panel.min.js\", \"https://cdn.jsdelivr.net/npm/@holoviz/geoviews@1.13.0/dist/geoviews.min.js\"];\n", + " const js_modules = [];\n", + " const js_exports = {};\n", + " const css_urls = [];\n", + " const inline_js = [ function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + "function(Bokeh) {} // ensure no trailing comma for IE\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " if ((root.Bokeh !== undefined) || (force === true)) {\n", + " for (let i = 0; i < inline_js.length; i++) {\n", + " try {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " } catch(e) {\n", + " if (!reloading) {\n", + " throw e;\n", + " }\n", + " }\n", + " }\n", + " // Cache old bokeh versions\n", + " if (Bokeh != undefined && !reloading) {\n", + " var NewBokeh = root.Bokeh;\n", + " if (Bokeh.versions === undefined) {\n", + " Bokeh.versions = new Map();\n", + " }\n", + " if (NewBokeh.version !== Bokeh.version) {\n", + " Bokeh.versions.set(NewBokeh.version, NewBokeh)\n", + " }\n", + " root.Bokeh = Bokeh;\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(run_inline_js, 100);\n", + " } else if (!root._bokeh_failed_load) {\n", + " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", + " root._bokeh_failed_load = true;\n", + " }\n", + " root._bokeh_is_initializing = false\n", + " }\n", + "\n", + " function load_or_wait() {\n", + " // Implement a backoff loop that tries to ensure we do not load multiple\n", + " // versions of Bokeh and its dependencies at the same time.\n", + " // In recent versions we use the root._bokeh_is_initializing flag\n", + " // to determine whether there is an ongoing attempt to initialize\n", + " // bokeh, however for backward compatibility we also try to ensure\n", + " // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n", + " // before older versions are fully initialized.\n", + " if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n", + " // If the timeout and bokeh was not successfully loaded we reset\n", + " // everything and try loading again\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_is_initializing = false;\n", + " root._bokeh_onload_callbacks = undefined;\n", + " root._bokeh_is_loading = 0\n", + " console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n", + " load_or_wait();\n", + " } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n", + " setTimeout(load_or_wait, 100);\n", + " } else {\n", + " root._bokeh_is_initializing = true\n", + " root._bokeh_onload_callbacks = []\n", + " const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n", + " if (!reloading && !bokeh_loaded) {\n", + " if (root.Bokeh) {\n", + " root.Bokeh = undefined;\n", + " }\n", + " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " }\n", + " load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + " }\n", + " // Give older versions of the autoload script a head-start to ensure\n", + " // they initialize before we start loading newer version.\n", + " setTimeout(load_or_wait, 100)\n", + "}(window));" + ], + "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n const reloading = false;\n const Bokeh = root.Bokeh;\n\n // Set a timeout for this load but only if we are not already initializing\n if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n // Don't load bokeh if it is still initializing\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n // There is nothing to load\n run_callbacks();\n return null;\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error(e) {\n const src_el = e.srcElement\n console.error(\"failed to load \" + (src_el.href || src_el.src));\n }\n\n const skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {}, 'shim': {}});\n root._bokeh_is_loading = css_urls.length + 0;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n const existing_stylesheets = []\n const links = document.getElementsByTagName('link')\n for (let i = 0; i < links.length; i++) {\n const link = links[i]\n if (link.href != null) {\n existing_stylesheets.push(link.href)\n }\n }\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const escaped = encodeURI(url)\n if (existing_stylesheets.indexOf(escaped) !== -1) {\n on_load()\n continue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } var existing_scripts = []\n const scripts = document.getElementsByTagName('script')\n for (let i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n existing_scripts.push(script.src)\n }\n }\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (let i = 0; i < js_modules.length; i++) {\n const url = js_modules[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n const url = js_exports[name];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.holoviz.org/panel/1.5.3/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.2.min.js\", \"https://cdn.holoviz.org/panel/1.5.3/dist/panel.min.js\", \"https://cdn.jsdelivr.net/npm/@holoviz/geoviews@1.13.0/dist/geoviews.min.js\"];\n const js_modules = [];\n const js_exports = {};\n const css_urls = [];\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (let i = 0; i < inline_js.length; i++) {\n try {\n inline_js[i].call(root, root.Bokeh);\n } catch(e) {\n if (!reloading) {\n throw e;\n }\n }\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n var NewBokeh = root.Bokeh;\n if (Bokeh.versions === undefined) {\n Bokeh.versions = new Map();\n }\n if (NewBokeh.version !== Bokeh.version) {\n Bokeh.versions.set(NewBokeh.version, NewBokeh)\n }\n root.Bokeh = Bokeh;\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n // If the timeout and bokeh was not successfully loaded we reset\n // everything and try loading again\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n root._bokeh_is_loading = 0\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n if (!reloading && !bokeh_loaded) {\n if (root.Bokeh) {\n root.Bokeh = undefined;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", + " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", + "}\n", + "\n", + "\n", + " function JupyterCommManager() {\n", + " }\n", + "\n", + " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", + " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", + " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", + " comm_manager.register_target(comm_id, function(comm) {\n", + " comm.on_msg(msg_handler);\n", + " });\n", + " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", + " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", + " comm.onMsg = msg_handler;\n", + " });\n", + " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", + " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", + " var messages = comm.messages[Symbol.asyncIterator]();\n", + " function processIteratorResult(result) {\n", + " var message = result.value;\n", + " console.log(message)\n", + " var content = {data: message.data, comm_id};\n", + " var buffers = []\n", + " for (var buffer of message.buffers || []) {\n", + " buffers.push(new DataView(buffer))\n", + " }\n", + " var metadata = message.metadata || {};\n", + " var msg = {content, buffers, metadata}\n", + " msg_handler(msg);\n", + " return messages.next().then(processIteratorResult);\n", + " }\n", + " return messages.next().then(processIteratorResult);\n", + " })\n", + " }\n", + " }\n", + "\n", + " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", + " if (comm_id in window.PyViz.comms) {\n", + " return window.PyViz.comms[comm_id];\n", + " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", + " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", + " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", + " if (msg_handler) {\n", + " comm.on_msg(msg_handler);\n", + " }\n", + " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", + " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", + " comm.open();\n", + " if (msg_handler) {\n", + " comm.onMsg = msg_handler;\n", + " }\n", + " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", + " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", + " comm_promise.then((comm) => {\n", + " window.PyViz.comms[comm_id] = comm;\n", + " if (msg_handler) {\n", + " var messages = comm.messages[Symbol.asyncIterator]();\n", + " function processIteratorResult(result) {\n", + " var message = result.value;\n", + " var content = {data: message.data};\n", + " var metadata = message.metadata || {comm_id};\n", + " var msg = {content, metadata}\n", + " msg_handler(msg);\n", + " return messages.next().then(processIteratorResult);\n", + " }\n", + " return messages.next().then(processIteratorResult);\n", + " }\n", + " }) \n", + " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", + " return comm_promise.then((comm) => {\n", + " comm.send(data, metadata, buffers, disposeOnDone);\n", + " });\n", + " };\n", + " var comm = {\n", + " send: sendClosure\n", + " };\n", + " }\n", + " window.PyViz.comms[comm_id] = comm;\n", + " return comm;\n", + " }\n", + " window.PyViz.comm_manager = new JupyterCommManager();\n", + " \n", + "\n", + "\n", + "var JS_MIME_TYPE = 'application/javascript';\n", + "var HTML_MIME_TYPE = 'text/html';\n", + "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", + "var CLASS_NAME = 'output';\n", + "\n", + "/**\n", + " * Render data to the DOM node\n", + " */\n", + "function render(props, node) {\n", + " var div = document.createElement(\"div\");\n", + " var script = document.createElement(\"script\");\n", + " node.appendChild(div);\n", + " node.appendChild(script);\n", + "}\n", + "\n", + "/**\n", + " * Handle when a new output is added\n", + " */\n", + "function handle_add_output(event, handle) {\n", + " var output_area = handle.output_area;\n", + " var output = handle.output;\n", + " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", + " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", + " if (id !== undefined) {\n", + " var nchildren = toinsert.length;\n", + " var html_node = toinsert[nchildren-1].children[0];\n", + " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", + " var scripts = [];\n", + " var nodelist = html_node.querySelectorAll(\"script\");\n", + " for (var i in nodelist) {\n", + " if (nodelist.hasOwnProperty(i)) {\n", + " scripts.push(nodelist[i])\n", + " }\n", + " }\n", + "\n", + " scripts.forEach( function (oldScript) {\n", + " var newScript = document.createElement(\"script\");\n", + " var attrs = [];\n", + " var nodemap = oldScript.attributes;\n", + " for (var j in nodemap) {\n", + " if (nodemap.hasOwnProperty(j)) {\n", + " attrs.push(nodemap[j])\n", + " }\n", + " }\n", + " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", + " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", + " oldScript.parentNode.replaceChild(newScript, oldScript);\n", + " });\n", + " if (JS_MIME_TYPE in output.data) {\n", + " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", + " }\n", + " output_area._hv_plot_id = id;\n", + " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", + " window.PyViz.plot_index[id] = Bokeh.index[id];\n", + " } else {\n", + " window.PyViz.plot_index[id] = null;\n", + " }\n", + " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", + " var bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " var script_attrs = bk_div.children[0].attributes;\n", + " for (var i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " }\n", + " // store reference to server id on output_area\n", + " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", + " }\n", + "}\n", + "\n", + "/**\n", + " * Handle when an output is cleared or removed\n", + " */\n", + "function handle_clear_output(event, handle) {\n", + " var id = handle.cell.output_area._hv_plot_id;\n", + " var server_id = handle.cell.output_area._bokeh_server_id;\n", + " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", + " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", + " if (server_id !== null) {\n", + " comm.send({event_type: 'server_delete', 'id': server_id});\n", + " return;\n", + " } else if (comm !== null) {\n", + " comm.send({event_type: 'delete', 'id': id});\n", + " }\n", + " delete PyViz.plot_index[id];\n", + " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", + " var doc = window.Bokeh.index[id].model.document\n", + " doc.clear();\n", + " const i = window.Bokeh.documents.indexOf(doc);\n", + " if (i > -1) {\n", + " window.Bokeh.documents.splice(i, 1);\n", + " }\n", + " }\n", + "}\n", + "\n", + "/**\n", + " * Handle kernel restart event\n", + " */\n", + "function handle_kernel_cleanup(event, handle) {\n", + " delete PyViz.comms[\"hv-extension-comm\"];\n", + " window.PyViz.plot_index = {}\n", + "}\n", + "\n", + "/**\n", + " * Handle update_display_data messages\n", + " */\n", + "function handle_update_output(event, handle) {\n", + " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", + " handle_add_output(event, handle)\n", + "}\n", + "\n", + "function register_renderer(events, OutputArea) {\n", + " function append_mime(data, metadata, element) {\n", + " // create a DOM node to render to\n", + " var toinsert = this.create_output_subarea(\n", + " metadata,\n", + " CLASS_NAME,\n", + " EXEC_MIME_TYPE\n", + " );\n", + " this.keyboard_manager.register_events(toinsert);\n", + " // Render to node\n", + " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", + " render(props, toinsert[0]);\n", + " element.append(toinsert);\n", + " return toinsert\n", + " }\n", + "\n", + " events.on('output_added.OutputArea', handle_add_output);\n", + " events.on('output_updated.OutputArea', handle_update_output);\n", + " events.on('clear_output.CodeCell', handle_clear_output);\n", + " events.on('delete.Cell', handle_clear_output);\n", + " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", + "\n", + " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", + " safe: true,\n", + " index: 0\n", + " });\n", + "}\n", + "\n", + "if (window.Jupyter !== undefined) {\n", + " try {\n", + " var events = require('base/js/events');\n", + " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", + " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", + " register_renderer(events, OutputArea);\n", + " }\n", + " } catch(err) {\n", + " }\n", + "}\n" + ], + "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.holoviews_exec.v0+json": "", + "text/html": [ + "
\n", + "
\n", + "
\n", + "" + ] + }, + "metadata": { + "application/vnd.holoviews_exec.v0+json": { + "id": "p1686" + } + }, + "output_type": "display_data" + }, + { + "data": {}, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.holoviews_exec.v0+json": "", + "text/html": [ + "
\n", + "
\n", + "
\n", + "" + ], + "text/plain": [ + ":Overlay\n", + " .WMTS.I :WMTS [Longitude,Latitude]\n", + " .Path.I :Path [Longitude,Latitude] (t_min_t_0)\n", + " .Points.I :Points [Longitude,Latitude] (t_min_t_0,triangle_angle)\n", + " .Path.II :Path [x,y]" + ] + }, + "execution_count": 9, + "metadata": { + "application/vnd.holoviews_exec.v0+json": { + "id": "p1688" + } + }, + "output_type": "execute_result" + } + ], + "source": [ + "# We can alos add the Closest Point of Approach to our map.\n", + "cpa_wgs84 = gpd.GeoDataFrame(\n", + " geometry=gpd.GeoSeries(cpa[\"geometry\"]), crs=\"EPSG:32632\"\n", + ").to_crs(\"EPSG:3857\")\n", + "# show trajectories with with CPA line\n", + "(\n", + " traj_collection_wgs84.hvplot(c=\"t_min_t_0\", cmap=\"Blues\")\n", + " * cpa_wgs84.hvplot(line_color=(0.8, 0.3, 0.3), line_width=3, line_alpha=0.8)\n", + ")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 7ab67bb60e028c8415de69c7ff49c172cce688f2 Mon Sep 17 00:00:00 2001 From: SiggyF Date: Sun, 13 Apr 2025 16:04:08 +0200 Subject: [PATCH 2/2] remove all output --- 2-analysis-examples/ship-cpa.ipynb | 2164 +--------------------------- 1 file changed, 14 insertions(+), 2150 deletions(-) diff --git a/2-analysis-examples/ship-cpa.ipynb b/2-analysis-examples/ship-cpa.ipynb index 46634cd..2d5d52c 100644 --- a/2-analysis-examples/ship-cpa.ipynb +++ b/2-analysis-examples/ship-cpa.ipynb @@ -2,621 +2,10 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "30f0a27a-919d-466f-9625-30d486ede07b", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " const force = true;\n", - " const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n", - " const reloading = false;\n", - " const Bokeh = root.Bokeh;\n", - "\n", - " // Set a timeout for this load but only if we are not already initializing\n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) {\n", - " if (callback != null)\n", - " callback();\n", - " });\n", - " } finally {\n", - " delete root._bokeh_onload_callbacks;\n", - " }\n", - " console.debug(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n", - " if (css_urls == null) css_urls = [];\n", - " if (js_urls == null) js_urls = [];\n", - " if (js_modules == null) js_modules = [];\n", - " if (js_exports == null) js_exports = {};\n", - "\n", - " root._bokeh_onload_callbacks.push(callback);\n", - "\n", - " if (root._bokeh_is_loading > 0) {\n", - " // Don't load bokeh if it is still initializing\n", - " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n", - " // There is nothing to load\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - "\n", - " function on_load() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", - " run_callbacks()\n", - " }\n", - " }\n", - " window._bokeh_on_load = on_load\n", - "\n", - " function on_error(e) {\n", - " const src_el = e.srcElement\n", - " console.error(\"failed to load \" + (src_el.href || src_el.src));\n", - " }\n", - "\n", - " const skip = [];\n", - " if (window.requirejs) {\n", - " window.requirejs.config({'packages': {}, 'paths': {}, 'shim': {}});\n", - " root._bokeh_is_loading = css_urls.length + 0;\n", - " } else {\n", - " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n", - " }\n", - "\n", - " const existing_stylesheets = []\n", - " const links = document.getElementsByTagName('link')\n", - " for (let i = 0; i < links.length; i++) {\n", - " const link = links[i]\n", - " if (link.href != null) {\n", - " existing_stylesheets.push(link.href)\n", - " }\n", - " }\n", - " for (let i = 0; i < css_urls.length; i++) {\n", - " const url = css_urls[i];\n", - " const escaped = encodeURI(url)\n", - " if (existing_stylesheets.indexOf(escaped) !== -1) {\n", - " on_load()\n", - " continue;\n", - " }\n", - " const element = document.createElement(\"link\");\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.rel = \"stylesheet\";\n", - " element.type = \"text/css\";\n", - " element.href = url;\n", - " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", - " document.body.appendChild(element);\n", - " } var existing_scripts = []\n", - " const scripts = document.getElementsByTagName('script')\n", - " for (let i = 0; i < scripts.length; i++) {\n", - " var script = scripts[i]\n", - " if (script.src != null) {\n", - " existing_scripts.push(script.src)\n", - " }\n", - " }\n", - " for (let i = 0; i < js_urls.length; i++) {\n", - " const url = js_urls[i];\n", - " const escaped = encodeURI(url)\n", - " if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n", - " if (!window.requirejs) {\n", - " on_load();\n", - " }\n", - " continue;\n", - " }\n", - " const element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " for (let i = 0; i < js_modules.length; i++) {\n", - " const url = js_modules[i];\n", - " const escaped = encodeURI(url)\n", - " if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n", - " if (!window.requirejs) {\n", - " on_load();\n", - " }\n", - " continue;\n", - " }\n", - " var element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " element.type = \"module\";\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " for (const name in js_exports) {\n", - " const url = js_exports[name];\n", - " const escaped = encodeURI(url)\n", - " if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n", - " if (!window.requirejs) {\n", - " on_load();\n", - " }\n", - " continue;\n", - " }\n", - " var element = document.createElement('script');\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.type = \"module\";\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " element.textContent = `\n", - " import ${name} from \"${url}\"\n", - " window.${name} = ${name}\n", - " window._bokeh_on_load()\n", - " `\n", - " document.head.appendChild(element);\n", - " }\n", - " if (!js_urls.length && !js_modules.length) {\n", - " on_load()\n", - " }\n", - " };\n", - "\n", - " function inject_raw_css(css) {\n", - " const element = document.createElement(\"style\");\n", - " element.appendChild(document.createTextNode(css));\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " const js_urls = [\"https://cdn.holoviz.org/panel/1.5.3/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.2.min.js\", \"https://cdn.holoviz.org/panel/1.5.3/dist/panel.min.js\"];\n", - " const js_modules = [];\n", - " const js_exports = {};\n", - " const css_urls = [];\n", - " const inline_js = [ function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - "function(Bokeh) {} // ensure no trailing comma for IE\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " if ((root.Bokeh !== undefined) || (force === true)) {\n", - " for (let i = 0; i < inline_js.length; i++) {\n", - " try {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " } catch(e) {\n", - " if (!reloading) {\n", - " throw e;\n", - " }\n", - " }\n", - " }\n", - " // Cache old bokeh versions\n", - " if (Bokeh != undefined && !reloading) {\n", - " var NewBokeh = root.Bokeh;\n", - " if (Bokeh.versions === undefined) {\n", - " Bokeh.versions = new Map();\n", - " }\n", - " if (NewBokeh.version !== Bokeh.version) {\n", - " Bokeh.versions.set(NewBokeh.version, NewBokeh)\n", - " }\n", - " root.Bokeh = Bokeh;\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " }\n", - " root._bokeh_is_initializing = false\n", - " }\n", - "\n", - " function load_or_wait() {\n", - " // Implement a backoff loop that tries to ensure we do not load multiple\n", - " // versions of Bokeh and its dependencies at the same time.\n", - " // In recent versions we use the root._bokeh_is_initializing flag\n", - " // to determine whether there is an ongoing attempt to initialize\n", - " // bokeh, however for backward compatibility we also try to ensure\n", - " // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n", - " // before older versions are fully initialized.\n", - " if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n", - " // If the timeout and bokeh was not successfully loaded we reset\n", - " // everything and try loading again\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_is_initializing = false;\n", - " root._bokeh_onload_callbacks = undefined;\n", - " root._bokeh_is_loading = 0\n", - " console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n", - " load_or_wait();\n", - " } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n", - " setTimeout(load_or_wait, 100);\n", - " } else {\n", - " root._bokeh_is_initializing = true\n", - " root._bokeh_onload_callbacks = []\n", - " const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n", - " if (!reloading && !bokeh_loaded) {\n", - " if (root.Bokeh) {\n", - " root.Bokeh = undefined;\n", - " }\n", - " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " }\n", - " load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n", - " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - " }\n", - " // Give older versions of the autoload script a head-start to ensure\n", - " // they initialize before we start loading newer version.\n", - " setTimeout(load_or_wait, 100)\n", - "}(window));" - ], - "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n const reloading = false;\n const Bokeh = root.Bokeh;\n\n // Set a timeout for this load but only if we are not already initializing\n if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n // Don't load bokeh if it is still initializing\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n // There is nothing to load\n run_callbacks();\n return null;\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error(e) {\n const src_el = e.srcElement\n console.error(\"failed to load \" + (src_el.href || src_el.src));\n }\n\n const skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {}, 'shim': {}});\n root._bokeh_is_loading = css_urls.length + 0;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n const existing_stylesheets = []\n const links = document.getElementsByTagName('link')\n for (let i = 0; i < links.length; i++) {\n const link = links[i]\n if (link.href != null) {\n existing_stylesheets.push(link.href)\n }\n }\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const escaped = encodeURI(url)\n if (existing_stylesheets.indexOf(escaped) !== -1) {\n on_load()\n continue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } var existing_scripts = []\n const scripts = document.getElementsByTagName('script')\n for (let i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n existing_scripts.push(script.src)\n }\n }\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (let i = 0; i < js_modules.length; i++) {\n const url = js_modules[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n const url = js_exports[name];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.holoviz.org/panel/1.5.3/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.2.min.js\", \"https://cdn.holoviz.org/panel/1.5.3/dist/panel.min.js\"];\n const js_modules = [];\n const js_exports = {};\n const css_urls = [];\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (let i = 0; i < inline_js.length; i++) {\n try {\n inline_js[i].call(root, root.Bokeh);\n } catch(e) {\n if (!reloading) {\n throw e;\n }\n }\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n var NewBokeh = root.Bokeh;\n if (Bokeh.versions === undefined) {\n Bokeh.versions = new Map();\n }\n if (NewBokeh.version !== Bokeh.version) {\n Bokeh.versions.set(NewBokeh.version, NewBokeh)\n }\n root.Bokeh = Bokeh;\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n // If the timeout and bokeh was not successfully loaded we reset\n // everything and try loading again\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n root._bokeh_is_loading = 0\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n if (!reloading && !bokeh_loaded) {\n if (root.Bokeh) {\n root.Bokeh = undefined;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "\n", - "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", - " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", - "}\n", - "\n", - "\n", - " function JupyterCommManager() {\n", - " }\n", - "\n", - " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", - " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", - " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", - " comm_manager.register_target(comm_id, function(comm) {\n", - " comm.on_msg(msg_handler);\n", - " });\n", - " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", - " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", - " comm.onMsg = msg_handler;\n", - " });\n", - " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", - " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", - " var messages = comm.messages[Symbol.asyncIterator]();\n", - " function processIteratorResult(result) {\n", - " var message = result.value;\n", - " console.log(message)\n", - " var content = {data: message.data, comm_id};\n", - " var buffers = []\n", - " for (var buffer of message.buffers || []) {\n", - " buffers.push(new DataView(buffer))\n", - " }\n", - " var metadata = message.metadata || {};\n", - " var msg = {content, buffers, metadata}\n", - " msg_handler(msg);\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " return messages.next().then(processIteratorResult);\n", - " })\n", - " }\n", - " }\n", - "\n", - " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", - " if (comm_id in window.PyViz.comms) {\n", - " return window.PyViz.comms[comm_id];\n", - " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", - " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", - " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", - " if (msg_handler) {\n", - " comm.on_msg(msg_handler);\n", - " }\n", - " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", - " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", - " comm.open();\n", - " if (msg_handler) {\n", - " comm.onMsg = msg_handler;\n", - " }\n", - " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", - " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", - " comm_promise.then((comm) => {\n", - " window.PyViz.comms[comm_id] = comm;\n", - " if (msg_handler) {\n", - " var messages = comm.messages[Symbol.asyncIterator]();\n", - " function processIteratorResult(result) {\n", - " var message = result.value;\n", - " var content = {data: message.data};\n", - " var metadata = message.metadata || {comm_id};\n", - " var msg = {content, metadata}\n", - " msg_handler(msg);\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " }) \n", - " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", - " return comm_promise.then((comm) => {\n", - " comm.send(data, metadata, buffers, disposeOnDone);\n", - " });\n", - " };\n", - " var comm = {\n", - " send: sendClosure\n", - " };\n", - " }\n", - " window.PyViz.comms[comm_id] = comm;\n", - " return comm;\n", - " }\n", - " window.PyViz.comm_manager = new JupyterCommManager();\n", - " \n", - "\n", - "\n", - "var JS_MIME_TYPE = 'application/javascript';\n", - "var HTML_MIME_TYPE = 'text/html';\n", - "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", - "var CLASS_NAME = 'output';\n", - "\n", - "/**\n", - " * Render data to the DOM node\n", - " */\n", - "function render(props, node) {\n", - " var div = document.createElement(\"div\");\n", - " var script = document.createElement(\"script\");\n", - " node.appendChild(div);\n", - " node.appendChild(script);\n", - "}\n", - "\n", - "/**\n", - " * Handle when a new output is added\n", - " */\n", - "function handle_add_output(event, handle) {\n", - " var output_area = handle.output_area;\n", - " var output = handle.output;\n", - " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - " if (id !== undefined) {\n", - " var nchildren = toinsert.length;\n", - " var html_node = toinsert[nchildren-1].children[0];\n", - " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var scripts = [];\n", - " var nodelist = html_node.querySelectorAll(\"script\");\n", - " for (var i in nodelist) {\n", - " if (nodelist.hasOwnProperty(i)) {\n", - " scripts.push(nodelist[i])\n", - " }\n", - " }\n", - "\n", - " scripts.forEach( function (oldScript) {\n", - " var newScript = document.createElement(\"script\");\n", - " var attrs = [];\n", - " var nodemap = oldScript.attributes;\n", - " for (var j in nodemap) {\n", - " if (nodemap.hasOwnProperty(j)) {\n", - " attrs.push(nodemap[j])\n", - " }\n", - " }\n", - " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", - " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", - " oldScript.parentNode.replaceChild(newScript, oldScript);\n", - " });\n", - " if (JS_MIME_TYPE in output.data) {\n", - " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", - " }\n", - " output_area._hv_plot_id = id;\n", - " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", - " window.PyViz.plot_index[id] = Bokeh.index[id];\n", - " } else {\n", - " window.PyViz.plot_index[id] = null;\n", - " }\n", - " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " var bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var script_attrs = bk_div.children[0].attributes;\n", - " for (var i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - "}\n", - "\n", - "/**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - "function handle_clear_output(event, handle) {\n", - " var id = handle.cell.output_area._hv_plot_id;\n", - " var server_id = handle.cell.output_area._bokeh_server_id;\n", - " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", - " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", - " if (server_id !== null) {\n", - " comm.send({event_type: 'server_delete', 'id': server_id});\n", - " return;\n", - " } else if (comm !== null) {\n", - " comm.send({event_type: 'delete', 'id': id});\n", - " }\n", - " delete PyViz.plot_index[id];\n", - " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", - " var doc = window.Bokeh.index[id].model.document\n", - " doc.clear();\n", - " const i = window.Bokeh.documents.indexOf(doc);\n", - " if (i > -1) {\n", - " window.Bokeh.documents.splice(i, 1);\n", - " }\n", - " }\n", - "}\n", - "\n", - "/**\n", - " * Handle kernel restart event\n", - " */\n", - "function handle_kernel_cleanup(event, handle) {\n", - " delete PyViz.comms[\"hv-extension-comm\"];\n", - " window.PyViz.plot_index = {}\n", - "}\n", - "\n", - "/**\n", - " * Handle update_display_data messages\n", - " */\n", - "function handle_update_output(event, handle) {\n", - " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", - " handle_add_output(event, handle)\n", - "}\n", - "\n", - "function register_renderer(events, OutputArea) {\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " var toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[0]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " events.on('output_added.OutputArea', handle_add_output);\n", - " events.on('output_updated.OutputArea', handle_update_output);\n", - " events.on('clear_output.CodeCell', handle_clear_output);\n", - " events.on('delete.Cell', handle_clear_output);\n", - " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", - "\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " safe: true,\n", - " index: 0\n", - " });\n", - "}\n", - "\n", - "if (window.Jupyter !== undefined) {\n", - " try {\n", - " var events = require('base/js/events');\n", - " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " } catch(err) {\n", - " }\n", - "}\n" - ], - "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.holoviews_exec.v0+json": "", - "text/html": [ - "
\n", - "
\n", - "
\n", - "" - ] - }, - "metadata": { - "application/vnd.holoviews_exec.v0+json": { - "id": "p1002" - } - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "import datetime\n", "from typing import Iterator\n", @@ -647,7 +36,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "7753cbbe-08e2-4f91-87f3-141bfccebeeb", "metadata": {}, "outputs": [], @@ -686,7 +75,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "baa1b901-c744-43fc-9dfe-4f98853636d3", "metadata": {}, "outputs": [], @@ -702,7 +91,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "f2c4b3cb-36c1-44f3-8770-2ba267354df3", "metadata": {}, "outputs": [], @@ -731,7 +120,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "6be51834-5ee6-447f-ba79-804f174f501a", "metadata": {}, "outputs": [], @@ -761,716 +150,10 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "e4a69b49-c978-49a3-a30b-4c07eada1d1f", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " const force = true;\n", - " const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n", - " const reloading = false;\n", - " const Bokeh = root.Bokeh;\n", - "\n", - " // Set a timeout for this load but only if we are not already initializing\n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) {\n", - " if (callback != null)\n", - " callback();\n", - " });\n", - " } finally {\n", - " delete root._bokeh_onload_callbacks;\n", - " }\n", - " console.debug(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n", - " if (css_urls == null) css_urls = [];\n", - " if (js_urls == null) js_urls = [];\n", - " if (js_modules == null) js_modules = [];\n", - " if (js_exports == null) js_exports = {};\n", - "\n", - " root._bokeh_onload_callbacks.push(callback);\n", - "\n", - " if (root._bokeh_is_loading > 0) {\n", - " // Don't load bokeh if it is still initializing\n", - " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n", - " // There is nothing to load\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - "\n", - " function on_load() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", - " run_callbacks()\n", - " }\n", - " }\n", - " window._bokeh_on_load = on_load\n", - "\n", - " function on_error(e) {\n", - " const src_el = e.srcElement\n", - " console.error(\"failed to load \" + (src_el.href || src_el.src));\n", - " }\n", - "\n", - " const skip = [];\n", - " if (window.requirejs) {\n", - " window.requirejs.config({'packages': {}, 'paths': {}, 'shim': {}});\n", - " root._bokeh_is_loading = css_urls.length + 0;\n", - " } else {\n", - " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n", - " }\n", - "\n", - " const existing_stylesheets = []\n", - " const links = document.getElementsByTagName('link')\n", - " for (let i = 0; i < links.length; i++) {\n", - " const link = links[i]\n", - " if (link.href != null) {\n", - " existing_stylesheets.push(link.href)\n", - " }\n", - " }\n", - " for (let i = 0; i < css_urls.length; i++) {\n", - " const url = css_urls[i];\n", - " const escaped = encodeURI(url)\n", - " if (existing_stylesheets.indexOf(escaped) !== -1) {\n", - " on_load()\n", - " continue;\n", - " }\n", - " const element = document.createElement(\"link\");\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.rel = \"stylesheet\";\n", - " element.type = \"text/css\";\n", - " element.href = url;\n", - " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", - " document.body.appendChild(element);\n", - " } var existing_scripts = []\n", - " const scripts = document.getElementsByTagName('script')\n", - " for (let i = 0; i < scripts.length; i++) {\n", - " var script = scripts[i]\n", - " if (script.src != null) {\n", - " existing_scripts.push(script.src)\n", - " }\n", - " }\n", - " for (let i = 0; i < js_urls.length; i++) {\n", - " const url = js_urls[i];\n", - " const escaped = encodeURI(url)\n", - " if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n", - " if (!window.requirejs) {\n", - " on_load();\n", - " }\n", - " continue;\n", - " }\n", - " const element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " for (let i = 0; i < js_modules.length; i++) {\n", - " const url = js_modules[i];\n", - " const escaped = encodeURI(url)\n", - " if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n", - " if (!window.requirejs) {\n", - " on_load();\n", - " }\n", - " continue;\n", - " }\n", - " var element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " element.type = \"module\";\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " for (const name in js_exports) {\n", - " const url = js_exports[name];\n", - " const escaped = encodeURI(url)\n", - " if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n", - " if (!window.requirejs) {\n", - " on_load();\n", - " }\n", - " continue;\n", - " }\n", - " var element = document.createElement('script');\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.type = \"module\";\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " element.textContent = `\n", - " import ${name} from \"${url}\"\n", - " window.${name} = ${name}\n", - " window._bokeh_on_load()\n", - " `\n", - " document.head.appendChild(element);\n", - " }\n", - " if (!js_urls.length && !js_modules.length) {\n", - " on_load()\n", - " }\n", - " };\n", - "\n", - " function inject_raw_css(css) {\n", - " const element = document.createElement(\"style\");\n", - " element.appendChild(document.createTextNode(css));\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " const js_urls = [\"https://cdn.holoviz.org/panel/1.5.3/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.2.min.js\", \"https://cdn.holoviz.org/panel/1.5.3/dist/panel.min.js\"];\n", - " const js_modules = [];\n", - " const js_exports = {};\n", - " const css_urls = [];\n", - " const inline_js = [ function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - "function(Bokeh) {} // ensure no trailing comma for IE\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " if ((root.Bokeh !== undefined) || (force === true)) {\n", - " for (let i = 0; i < inline_js.length; i++) {\n", - " try {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " } catch(e) {\n", - " if (!reloading) {\n", - " throw e;\n", - " }\n", - " }\n", - " }\n", - " // Cache old bokeh versions\n", - " if (Bokeh != undefined && !reloading) {\n", - " var NewBokeh = root.Bokeh;\n", - " if (Bokeh.versions === undefined) {\n", - " Bokeh.versions = new Map();\n", - " }\n", - " if (NewBokeh.version !== Bokeh.version) {\n", - " Bokeh.versions.set(NewBokeh.version, NewBokeh)\n", - " }\n", - " root.Bokeh = Bokeh;\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " }\n", - " root._bokeh_is_initializing = false\n", - " }\n", - "\n", - " function load_or_wait() {\n", - " // Implement a backoff loop that tries to ensure we do not load multiple\n", - " // versions of Bokeh and its dependencies at the same time.\n", - " // In recent versions we use the root._bokeh_is_initializing flag\n", - " // to determine whether there is an ongoing attempt to initialize\n", - " // bokeh, however for backward compatibility we also try to ensure\n", - " // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n", - " // before older versions are fully initialized.\n", - " if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n", - " // If the timeout and bokeh was not successfully loaded we reset\n", - " // everything and try loading again\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_is_initializing = false;\n", - " root._bokeh_onload_callbacks = undefined;\n", - " root._bokeh_is_loading = 0\n", - " console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n", - " load_or_wait();\n", - " } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n", - " setTimeout(load_or_wait, 100);\n", - " } else {\n", - " root._bokeh_is_initializing = true\n", - " root._bokeh_onload_callbacks = []\n", - " const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n", - " if (!reloading && !bokeh_loaded) {\n", - " if (root.Bokeh) {\n", - " root.Bokeh = undefined;\n", - " }\n", - " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " }\n", - " load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n", - " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - " }\n", - " // Give older versions of the autoload script a head-start to ensure\n", - " // they initialize before we start loading newer version.\n", - " setTimeout(load_or_wait, 100)\n", - "}(window));" - ], - "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n const reloading = false;\n const Bokeh = root.Bokeh;\n\n // Set a timeout for this load but only if we are not already initializing\n if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n // Don't load bokeh if it is still initializing\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n // There is nothing to load\n run_callbacks();\n return null;\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error(e) {\n const src_el = e.srcElement\n console.error(\"failed to load \" + (src_el.href || src_el.src));\n }\n\n const skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {}, 'shim': {}});\n root._bokeh_is_loading = css_urls.length + 0;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n const existing_stylesheets = []\n const links = document.getElementsByTagName('link')\n for (let i = 0; i < links.length; i++) {\n const link = links[i]\n if (link.href != null) {\n existing_stylesheets.push(link.href)\n }\n }\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const escaped = encodeURI(url)\n if (existing_stylesheets.indexOf(escaped) !== -1) {\n on_load()\n continue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } var existing_scripts = []\n const scripts = document.getElementsByTagName('script')\n for (let i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n existing_scripts.push(script.src)\n }\n }\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (let i = 0; i < js_modules.length; i++) {\n const url = js_modules[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n const url = js_exports[name];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.holoviz.org/panel/1.5.3/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.2.min.js\", \"https://cdn.holoviz.org/panel/1.5.3/dist/panel.min.js\"];\n const js_modules = [];\n const js_exports = {};\n const css_urls = [];\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (let i = 0; i < inline_js.length; i++) {\n try {\n inline_js[i].call(root, root.Bokeh);\n } catch(e) {\n if (!reloading) {\n throw e;\n }\n }\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n var NewBokeh = root.Bokeh;\n if (Bokeh.versions === undefined) {\n Bokeh.versions = new Map();\n }\n if (NewBokeh.version !== Bokeh.version) {\n Bokeh.versions.set(NewBokeh.version, NewBokeh)\n }\n root.Bokeh = Bokeh;\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n // If the timeout and bokeh was not successfully loaded we reset\n // everything and try loading again\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n root._bokeh_is_loading = 0\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n if (!reloading && !bokeh_loaded) {\n if (root.Bokeh) {\n root.Bokeh = undefined;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "\n", - "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", - " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", - "}\n", - "\n", - "\n", - " function JupyterCommManager() {\n", - " }\n", - "\n", - " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", - " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", - " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", - " comm_manager.register_target(comm_id, function(comm) {\n", - " comm.on_msg(msg_handler);\n", - " });\n", - " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", - " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", - " comm.onMsg = msg_handler;\n", - " });\n", - " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", - " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", - " var messages = comm.messages[Symbol.asyncIterator]();\n", - " function processIteratorResult(result) {\n", - " var message = result.value;\n", - " console.log(message)\n", - " var content = {data: message.data, comm_id};\n", - " var buffers = []\n", - " for (var buffer of message.buffers || []) {\n", - " buffers.push(new DataView(buffer))\n", - " }\n", - " var metadata = message.metadata || {};\n", - " var msg = {content, buffers, metadata}\n", - " msg_handler(msg);\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " return messages.next().then(processIteratorResult);\n", - " })\n", - " }\n", - " }\n", - "\n", - " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", - " if (comm_id in window.PyViz.comms) {\n", - " return window.PyViz.comms[comm_id];\n", - " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", - " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", - " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", - " if (msg_handler) {\n", - " comm.on_msg(msg_handler);\n", - " }\n", - " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", - " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", - " comm.open();\n", - " if (msg_handler) {\n", - " comm.onMsg = msg_handler;\n", - " }\n", - " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", - " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", - " comm_promise.then((comm) => {\n", - " window.PyViz.comms[comm_id] = comm;\n", - " if (msg_handler) {\n", - " var messages = comm.messages[Symbol.asyncIterator]();\n", - " function processIteratorResult(result) {\n", - " var message = result.value;\n", - " var content = {data: message.data};\n", - " var metadata = message.metadata || {comm_id};\n", - " var msg = {content, metadata}\n", - " msg_handler(msg);\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " }) \n", - " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", - " return comm_promise.then((comm) => {\n", - " comm.send(data, metadata, buffers, disposeOnDone);\n", - " });\n", - " };\n", - " var comm = {\n", - " send: sendClosure\n", - " };\n", - " }\n", - " window.PyViz.comms[comm_id] = comm;\n", - " return comm;\n", - " }\n", - " window.PyViz.comm_manager = new JupyterCommManager();\n", - " \n", - "\n", - "\n", - "var JS_MIME_TYPE = 'application/javascript';\n", - "var HTML_MIME_TYPE = 'text/html';\n", - "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", - "var CLASS_NAME = 'output';\n", - "\n", - "/**\n", - " * Render data to the DOM node\n", - " */\n", - "function render(props, node) {\n", - " var div = document.createElement(\"div\");\n", - " var script = document.createElement(\"script\");\n", - " node.appendChild(div);\n", - " node.appendChild(script);\n", - "}\n", - "\n", - "/**\n", - " * Handle when a new output is added\n", - " */\n", - "function handle_add_output(event, handle) {\n", - " var output_area = handle.output_area;\n", - " var output = handle.output;\n", - " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - " if (id !== undefined) {\n", - " var nchildren = toinsert.length;\n", - " var html_node = toinsert[nchildren-1].children[0];\n", - " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var scripts = [];\n", - " var nodelist = html_node.querySelectorAll(\"script\");\n", - " for (var i in nodelist) {\n", - " if (nodelist.hasOwnProperty(i)) {\n", - " scripts.push(nodelist[i])\n", - " }\n", - " }\n", - "\n", - " scripts.forEach( function (oldScript) {\n", - " var newScript = document.createElement(\"script\");\n", - " var attrs = [];\n", - " var nodemap = oldScript.attributes;\n", - " for (var j in nodemap) {\n", - " if (nodemap.hasOwnProperty(j)) {\n", - " attrs.push(nodemap[j])\n", - " }\n", - " }\n", - " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", - " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", - " oldScript.parentNode.replaceChild(newScript, oldScript);\n", - " });\n", - " if (JS_MIME_TYPE in output.data) {\n", - " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", - " }\n", - " output_area._hv_plot_id = id;\n", - " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", - " window.PyViz.plot_index[id] = Bokeh.index[id];\n", - " } else {\n", - " window.PyViz.plot_index[id] = null;\n", - " }\n", - " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " var bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var script_attrs = bk_div.children[0].attributes;\n", - " for (var i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - "}\n", - "\n", - "/**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - "function handle_clear_output(event, handle) {\n", - " var id = handle.cell.output_area._hv_plot_id;\n", - " var server_id = handle.cell.output_area._bokeh_server_id;\n", - " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", - " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", - " if (server_id !== null) {\n", - " comm.send({event_type: 'server_delete', 'id': server_id});\n", - " return;\n", - " } else if (comm !== null) {\n", - " comm.send({event_type: 'delete', 'id': id});\n", - " }\n", - " delete PyViz.plot_index[id];\n", - " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", - " var doc = window.Bokeh.index[id].model.document\n", - " doc.clear();\n", - " const i = window.Bokeh.documents.indexOf(doc);\n", - " if (i > -1) {\n", - " window.Bokeh.documents.splice(i, 1);\n", - " }\n", - " }\n", - "}\n", - "\n", - "/**\n", - " * Handle kernel restart event\n", - " */\n", - "function handle_kernel_cleanup(event, handle) {\n", - " delete PyViz.comms[\"hv-extension-comm\"];\n", - " window.PyViz.plot_index = {}\n", - "}\n", - "\n", - "/**\n", - " * Handle update_display_data messages\n", - " */\n", - "function handle_update_output(event, handle) {\n", - " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", - " handle_add_output(event, handle)\n", - "}\n", - "\n", - "function register_renderer(events, OutputArea) {\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " var toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[0]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " events.on('output_added.OutputArea', handle_add_output);\n", - " events.on('output_updated.OutputArea', handle_update_output);\n", - " events.on('clear_output.CodeCell', handle_clear_output);\n", - " events.on('delete.Cell', handle_clear_output);\n", - " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", - "\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " safe: true,\n", - " index: 0\n", - " });\n", - "}\n", - "\n", - "if (window.Jupyter !== undefined) {\n", - " try {\n", - " var events = require('base/js/events');\n", - " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " } catch(err) {\n", - " }\n", - "}\n" - ], - "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.holoviews_exec.v0+json": "", - "text/html": [ - "
\n", - "
\n", - "
\n", - "" - ] - }, - "metadata": { - "application/vnd.holoviews_exec.v0+json": { - "id": "p1004" - } - }, - "output_type": "display_data" - }, - { - "data": {}, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.holoviews_exec.v0+json": "", - "text/html": [ - "
\n", - "
\n", - "
\n", - "" - ], - "text/plain": [ - ":Overlay\n", - " .WMTS.I :WMTS [Longitude,Latitude]\n", - " .Path.I :Path [Longitude,Latitude] (t_min_t_0)\n", - " .Points.I :Points [Longitude,Latitude] (t_min_t_0,triangle_angle)" - ] - }, - "execution_count": 6, - "metadata": { - "application/vnd.holoviews_exec.v0+json": { - "id": "p1015" - } - }, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# create a variant in wgs84 to show a plot\n", "traj_collection_wgs84 = mpd.TrajectoryCollection(\n", @@ -1494,111 +177,10 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "5075ff5d-9222-4b49-814b-c436b9c7821c", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
t_att_togeometrydiststatus
1302017-07-05 19:08:31.8926602260.654740LINESTRING (669670.78 6397464.373, 669566.588 ...380.204079approaching
1312017-07-05 19:08:35.000000000-3.393321LINESTRING (669676.948 6397452.972, 669547.789...381.089295diverging
1292017-07-05 19:08:25.000000000-22.385399LINESTRING (669659.084 6397485.995, 669608.109...381.202006diverging
1282017-07-05 19:08:25.0000000001.933643LINESTRING (669659.084 6397485.995, 669608.109...381.202006converging
1322017-07-05 19:08:36.000000000-0.540582LINESTRING (669678.62 6397449.419, 669541.74 6...381.746013diverging
\n", - "
" - ], - "text/plain": [ - " t_at t_to \\\n", - "130 2017-07-05 19:08:31.892660226 0.654740 \n", - "131 2017-07-05 19:08:35.000000000 -3.393321 \n", - "129 2017-07-05 19:08:25.000000000 -22.385399 \n", - "128 2017-07-05 19:08:25.000000000 1.933643 \n", - "132 2017-07-05 19:08:36.000000000 -0.540582 \n", - "\n", - " geometry dist \\\n", - "130 LINESTRING (669670.78 6397464.373, 669566.588 ... 380.204079 \n", - "131 LINESTRING (669676.948 6397452.972, 669547.789... 381.089295 \n", - "129 LINESTRING (669659.084 6397485.995, 669608.109... 381.202006 \n", - "128 LINESTRING (669659.084 6397485.995, 669608.109... 381.202006 \n", - "132 LINESTRING (669678.62 6397449.419, 669541.74 6... 381.746013 \n", - "\n", - " status \n", - "130 approaching \n", - "131 diverging \n", - "129 diverging \n", - "128 converging \n", - "132 diverging " - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "cpa_calc = movingpandas.cpa.CPACalculator(traj_a, traj_b)\n", "cpa_df = cpa_calc.segments_gdf()\n", @@ -1618,21 +200,10 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "8027c913-1bdd-4f3b-b2d0-9d4e97b9d24b", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "fig, ax = plt.subplots()\n", "\n", @@ -1657,717 +228,10 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "79146a33-d758-4c5e-a9dc-b2df5d5f5c5b", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " const force = true;\n", - " const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n", - " const reloading = false;\n", - " const Bokeh = root.Bokeh;\n", - "\n", - " // Set a timeout for this load but only if we are not already initializing\n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) {\n", - " if (callback != null)\n", - " callback();\n", - " });\n", - " } finally {\n", - " delete root._bokeh_onload_callbacks;\n", - " }\n", - " console.debug(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n", - " if (css_urls == null) css_urls = [];\n", - " if (js_urls == null) js_urls = [];\n", - " if (js_modules == null) js_modules = [];\n", - " if (js_exports == null) js_exports = {};\n", - "\n", - " root._bokeh_onload_callbacks.push(callback);\n", - "\n", - " if (root._bokeh_is_loading > 0) {\n", - " // Don't load bokeh if it is still initializing\n", - " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n", - " // There is nothing to load\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - "\n", - " function on_load() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", - " run_callbacks()\n", - " }\n", - " }\n", - " window._bokeh_on_load = on_load\n", - "\n", - " function on_error(e) {\n", - " const src_el = e.srcElement\n", - " console.error(\"failed to load \" + (src_el.href || src_el.src));\n", - " }\n", - "\n", - " const skip = [];\n", - " if (window.requirejs) {\n", - " window.requirejs.config({'packages': {}, 'paths': {}, 'shim': {}});\n", - " root._bokeh_is_loading = css_urls.length + 0;\n", - " } else {\n", - " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n", - " }\n", - "\n", - " const existing_stylesheets = []\n", - " const links = document.getElementsByTagName('link')\n", - " for (let i = 0; i < links.length; i++) {\n", - " const link = links[i]\n", - " if (link.href != null) {\n", - " existing_stylesheets.push(link.href)\n", - " }\n", - " }\n", - " for (let i = 0; i < css_urls.length; i++) {\n", - " const url = css_urls[i];\n", - " const escaped = encodeURI(url)\n", - " if (existing_stylesheets.indexOf(escaped) !== -1) {\n", - " on_load()\n", - " continue;\n", - " }\n", - " const element = document.createElement(\"link\");\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.rel = \"stylesheet\";\n", - " element.type = \"text/css\";\n", - " element.href = url;\n", - " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", - " document.body.appendChild(element);\n", - " } var existing_scripts = []\n", - " const scripts = document.getElementsByTagName('script')\n", - " for (let i = 0; i < scripts.length; i++) {\n", - " var script = scripts[i]\n", - " if (script.src != null) {\n", - " existing_scripts.push(script.src)\n", - " }\n", - " }\n", - " for (let i = 0; i < js_urls.length; i++) {\n", - " const url = js_urls[i];\n", - " const escaped = encodeURI(url)\n", - " if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n", - " if (!window.requirejs) {\n", - " on_load();\n", - " }\n", - " continue;\n", - " }\n", - " const element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " for (let i = 0; i < js_modules.length; i++) {\n", - " const url = js_modules[i];\n", - " const escaped = encodeURI(url)\n", - " if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n", - " if (!window.requirejs) {\n", - " on_load();\n", - " }\n", - " continue;\n", - " }\n", - " var element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " element.type = \"module\";\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " for (const name in js_exports) {\n", - " const url = js_exports[name];\n", - " const escaped = encodeURI(url)\n", - " if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n", - " if (!window.requirejs) {\n", - " on_load();\n", - " }\n", - " continue;\n", - " }\n", - " var element = document.createElement('script');\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.type = \"module\";\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " element.textContent = `\n", - " import ${name} from \"${url}\"\n", - " window.${name} = ${name}\n", - " window._bokeh_on_load()\n", - " `\n", - " document.head.appendChild(element);\n", - " }\n", - " if (!js_urls.length && !js_modules.length) {\n", - " on_load()\n", - " }\n", - " };\n", - "\n", - " function inject_raw_css(css) {\n", - " const element = document.createElement(\"style\");\n", - " element.appendChild(document.createTextNode(css));\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " const js_urls = [\"https://cdn.holoviz.org/panel/1.5.3/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.2.min.js\", \"https://cdn.holoviz.org/panel/1.5.3/dist/panel.min.js\", \"https://cdn.jsdelivr.net/npm/@holoviz/geoviews@1.13.0/dist/geoviews.min.js\"];\n", - " const js_modules = [];\n", - " const js_exports = {};\n", - " const css_urls = [];\n", - " const inline_js = [ function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - "function(Bokeh) {} // ensure no trailing comma for IE\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " if ((root.Bokeh !== undefined) || (force === true)) {\n", - " for (let i = 0; i < inline_js.length; i++) {\n", - " try {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " } catch(e) {\n", - " if (!reloading) {\n", - " throw e;\n", - " }\n", - " }\n", - " }\n", - " // Cache old bokeh versions\n", - " if (Bokeh != undefined && !reloading) {\n", - " var NewBokeh = root.Bokeh;\n", - " if (Bokeh.versions === undefined) {\n", - " Bokeh.versions = new Map();\n", - " }\n", - " if (NewBokeh.version !== Bokeh.version) {\n", - " Bokeh.versions.set(NewBokeh.version, NewBokeh)\n", - " }\n", - " root.Bokeh = Bokeh;\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " }\n", - " root._bokeh_is_initializing = false\n", - " }\n", - "\n", - " function load_or_wait() {\n", - " // Implement a backoff loop that tries to ensure we do not load multiple\n", - " // versions of Bokeh and its dependencies at the same time.\n", - " // In recent versions we use the root._bokeh_is_initializing flag\n", - " // to determine whether there is an ongoing attempt to initialize\n", - " // bokeh, however for backward compatibility we also try to ensure\n", - " // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n", - " // before older versions are fully initialized.\n", - " if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n", - " // If the timeout and bokeh was not successfully loaded we reset\n", - " // everything and try loading again\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_is_initializing = false;\n", - " root._bokeh_onload_callbacks = undefined;\n", - " root._bokeh_is_loading = 0\n", - " console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n", - " load_or_wait();\n", - " } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n", - " setTimeout(load_or_wait, 100);\n", - " } else {\n", - " root._bokeh_is_initializing = true\n", - " root._bokeh_onload_callbacks = []\n", - " const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n", - " if (!reloading && !bokeh_loaded) {\n", - " if (root.Bokeh) {\n", - " root.Bokeh = undefined;\n", - " }\n", - " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " }\n", - " load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n", - " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - " }\n", - " // Give older versions of the autoload script a head-start to ensure\n", - " // they initialize before we start loading newer version.\n", - " setTimeout(load_or_wait, 100)\n", - "}(window));" - ], - "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n const reloading = false;\n const Bokeh = root.Bokeh;\n\n // Set a timeout for this load but only if we are not already initializing\n if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n // Don't load bokeh if it is still initializing\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n // There is nothing to load\n run_callbacks();\n return null;\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error(e) {\n const src_el = e.srcElement\n console.error(\"failed to load \" + (src_el.href || src_el.src));\n }\n\n const skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {}, 'shim': {}});\n root._bokeh_is_loading = css_urls.length + 0;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n const existing_stylesheets = []\n const links = document.getElementsByTagName('link')\n for (let i = 0; i < links.length; i++) {\n const link = links[i]\n if (link.href != null) {\n existing_stylesheets.push(link.href)\n }\n }\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const escaped = encodeURI(url)\n if (existing_stylesheets.indexOf(escaped) !== -1) {\n on_load()\n continue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } var existing_scripts = []\n const scripts = document.getElementsByTagName('script')\n for (let i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n existing_scripts.push(script.src)\n }\n }\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (let i = 0; i < js_modules.length; i++) {\n const url = js_modules[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n const url = js_exports[name];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.holoviz.org/panel/1.5.3/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.2.min.js\", \"https://cdn.holoviz.org/panel/1.5.3/dist/panel.min.js\", \"https://cdn.jsdelivr.net/npm/@holoviz/geoviews@1.13.0/dist/geoviews.min.js\"];\n const js_modules = [];\n const js_exports = {};\n const css_urls = [];\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (let i = 0; i < inline_js.length; i++) {\n try {\n inline_js[i].call(root, root.Bokeh);\n } catch(e) {\n if (!reloading) {\n throw e;\n }\n }\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n var NewBokeh = root.Bokeh;\n if (Bokeh.versions === undefined) {\n Bokeh.versions = new Map();\n }\n if (NewBokeh.version !== Bokeh.version) {\n Bokeh.versions.set(NewBokeh.version, NewBokeh)\n }\n root.Bokeh = Bokeh;\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n // If the timeout and bokeh was not successfully loaded we reset\n // everything and try loading again\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n root._bokeh_is_loading = 0\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n if (!reloading && !bokeh_loaded) {\n if (root.Bokeh) {\n root.Bokeh = undefined;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "\n", - "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", - " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", - "}\n", - "\n", - "\n", - " function JupyterCommManager() {\n", - " }\n", - "\n", - " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", - " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", - " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", - " comm_manager.register_target(comm_id, function(comm) {\n", - " comm.on_msg(msg_handler);\n", - " });\n", - " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", - " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", - " comm.onMsg = msg_handler;\n", - " });\n", - " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", - " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", - " var messages = comm.messages[Symbol.asyncIterator]();\n", - " function processIteratorResult(result) {\n", - " var message = result.value;\n", - " console.log(message)\n", - " var content = {data: message.data, comm_id};\n", - " var buffers = []\n", - " for (var buffer of message.buffers || []) {\n", - " buffers.push(new DataView(buffer))\n", - " }\n", - " var metadata = message.metadata || {};\n", - " var msg = {content, buffers, metadata}\n", - " msg_handler(msg);\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " return messages.next().then(processIteratorResult);\n", - " })\n", - " }\n", - " }\n", - "\n", - " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", - " if (comm_id in window.PyViz.comms) {\n", - " return window.PyViz.comms[comm_id];\n", - " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", - " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", - " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", - " if (msg_handler) {\n", - " comm.on_msg(msg_handler);\n", - " }\n", - " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", - " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", - " comm.open();\n", - " if (msg_handler) {\n", - " comm.onMsg = msg_handler;\n", - " }\n", - " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", - " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", - " comm_promise.then((comm) => {\n", - " window.PyViz.comms[comm_id] = comm;\n", - " if (msg_handler) {\n", - " var messages = comm.messages[Symbol.asyncIterator]();\n", - " function processIteratorResult(result) {\n", - " var message = result.value;\n", - " var content = {data: message.data};\n", - " var metadata = message.metadata || {comm_id};\n", - " var msg = {content, metadata}\n", - " msg_handler(msg);\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " }) \n", - " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", - " return comm_promise.then((comm) => {\n", - " comm.send(data, metadata, buffers, disposeOnDone);\n", - " });\n", - " };\n", - " var comm = {\n", - " send: sendClosure\n", - " };\n", - " }\n", - " window.PyViz.comms[comm_id] = comm;\n", - " return comm;\n", - " }\n", - " window.PyViz.comm_manager = new JupyterCommManager();\n", - " \n", - "\n", - "\n", - "var JS_MIME_TYPE = 'application/javascript';\n", - "var HTML_MIME_TYPE = 'text/html';\n", - "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", - "var CLASS_NAME = 'output';\n", - "\n", - "/**\n", - " * Render data to the DOM node\n", - " */\n", - "function render(props, node) {\n", - " var div = document.createElement(\"div\");\n", - " var script = document.createElement(\"script\");\n", - " node.appendChild(div);\n", - " node.appendChild(script);\n", - "}\n", - "\n", - "/**\n", - " * Handle when a new output is added\n", - " */\n", - "function handle_add_output(event, handle) {\n", - " var output_area = handle.output_area;\n", - " var output = handle.output;\n", - " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - " if (id !== undefined) {\n", - " var nchildren = toinsert.length;\n", - " var html_node = toinsert[nchildren-1].children[0];\n", - " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var scripts = [];\n", - " var nodelist = html_node.querySelectorAll(\"script\");\n", - " for (var i in nodelist) {\n", - " if (nodelist.hasOwnProperty(i)) {\n", - " scripts.push(nodelist[i])\n", - " }\n", - " }\n", - "\n", - " scripts.forEach( function (oldScript) {\n", - " var newScript = document.createElement(\"script\");\n", - " var attrs = [];\n", - " var nodemap = oldScript.attributes;\n", - " for (var j in nodemap) {\n", - " if (nodemap.hasOwnProperty(j)) {\n", - " attrs.push(nodemap[j])\n", - " }\n", - " }\n", - " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", - " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", - " oldScript.parentNode.replaceChild(newScript, oldScript);\n", - " });\n", - " if (JS_MIME_TYPE in output.data) {\n", - " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", - " }\n", - " output_area._hv_plot_id = id;\n", - " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", - " window.PyViz.plot_index[id] = Bokeh.index[id];\n", - " } else {\n", - " window.PyViz.plot_index[id] = null;\n", - " }\n", - " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " var bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var script_attrs = bk_div.children[0].attributes;\n", - " for (var i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - "}\n", - "\n", - "/**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - "function handle_clear_output(event, handle) {\n", - " var id = handle.cell.output_area._hv_plot_id;\n", - " var server_id = handle.cell.output_area._bokeh_server_id;\n", - " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", - " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", - " if (server_id !== null) {\n", - " comm.send({event_type: 'server_delete', 'id': server_id});\n", - " return;\n", - " } else if (comm !== null) {\n", - " comm.send({event_type: 'delete', 'id': id});\n", - " }\n", - " delete PyViz.plot_index[id];\n", - " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", - " var doc = window.Bokeh.index[id].model.document\n", - " doc.clear();\n", - " const i = window.Bokeh.documents.indexOf(doc);\n", - " if (i > -1) {\n", - " window.Bokeh.documents.splice(i, 1);\n", - " }\n", - " }\n", - "}\n", - "\n", - "/**\n", - " * Handle kernel restart event\n", - " */\n", - "function handle_kernel_cleanup(event, handle) {\n", - " delete PyViz.comms[\"hv-extension-comm\"];\n", - " window.PyViz.plot_index = {}\n", - "}\n", - "\n", - "/**\n", - " * Handle update_display_data messages\n", - " */\n", - "function handle_update_output(event, handle) {\n", - " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", - " handle_add_output(event, handle)\n", - "}\n", - "\n", - "function register_renderer(events, OutputArea) {\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " var toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[0]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " events.on('output_added.OutputArea', handle_add_output);\n", - " events.on('output_updated.OutputArea', handle_update_output);\n", - " events.on('clear_output.CodeCell', handle_clear_output);\n", - " events.on('delete.Cell', handle_clear_output);\n", - " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", - "\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " safe: true,\n", - " index: 0\n", - " });\n", - "}\n", - "\n", - "if (window.Jupyter !== undefined) {\n", - " try {\n", - " var events = require('base/js/events');\n", - " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " } catch(err) {\n", - " }\n", - "}\n" - ], - "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.holoviews_exec.v0+json": "", - "text/html": [ - "
\n", - "
\n", - "
\n", - "" - ] - }, - "metadata": { - "application/vnd.holoviews_exec.v0+json": { - "id": "p1686" - } - }, - "output_type": "display_data" - }, - { - "data": {}, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.holoviews_exec.v0+json": "", - "text/html": [ - "
\n", - "
\n", - "
\n", - "" - ], - "text/plain": [ - ":Overlay\n", - " .WMTS.I :WMTS [Longitude,Latitude]\n", - " .Path.I :Path [Longitude,Latitude] (t_min_t_0)\n", - " .Points.I :Points [Longitude,Latitude] (t_min_t_0,triangle_angle)\n", - " .Path.II :Path [x,y]" - ] - }, - "execution_count": 9, - "metadata": { - "application/vnd.holoviews_exec.v0+json": { - "id": "p1688" - } - }, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# We can alos add the Closest Point of Approach to our map.\n", "cpa_wgs84 = gpd.GeoDataFrame(\n",