mewamuwa commited on
Commit
82cab59
·
verified ·
1 Parent(s): 813e1bc

Kode der definerer distance to peaks variabel

Browse files
Distance_to_peak-variabel_philip.ipynb ADDED
@@ -0,0 +1,457 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "id": "a39df92a",
7
+ "metadata": {},
8
+ "outputs": [
9
+ {
10
+ "data": {
11
+ "text/html": [
12
+ "<script type=\"esms-options\">{\"shimMode\": true}</script><style>*[data-root-id],\n",
13
+ "*[data-root-id] > * {\n",
14
+ " box-sizing: border-box;\n",
15
+ " font-family: var(--jp-ui-font-family);\n",
16
+ " font-size: var(--jp-ui-font-size1);\n",
17
+ " color: var(--vscode-editor-foreground, var(--jp-ui-font-color1));\n",
18
+ "}\n",
19
+ "\n",
20
+ "/* Override VSCode background color */\n",
21
+ ".cell-output-ipywidget-background:has(\n",
22
+ " > .cell-output-ipywidget-background > .lm-Widget > *[data-root-id]\n",
23
+ " ),\n",
24
+ ".cell-output-ipywidget-background:has(> .lm-Widget > *[data-root-id]) {\n",
25
+ " background-color: transparent !important;\n",
26
+ "}\n",
27
+ "</style>"
28
+ ]
29
+ },
30
+ "metadata": {},
31
+ "output_type": "display_data"
32
+ },
33
+ {
34
+ "data": {
35
+ "application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n const py_version = '3.7.3'.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.7.0/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.7.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.7.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.7.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.7.3.min.js\", \"https://cdn.holoviz.org/panel/1.7.0/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));",
36
+ "application/vnd.holoviews_load.v0+json": ""
37
+ },
38
+ "metadata": {},
39
+ "output_type": "display_data"
40
+ },
41
+ {
42
+ "data": {
43
+ "application/javascript": "\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",
44
+ "application/vnd.holoviews_load.v0+json": ""
45
+ },
46
+ "metadata": {},
47
+ "output_type": "display_data"
48
+ },
49
+ {
50
+ "data": {
51
+ "application/vnd.holoviews_exec.v0+json": "",
52
+ "text/html": [
53
+ "<div id='bf174fcc-257c-470c-b445-9731bb40e120'>\n",
54
+ " <div id=\"a8ba9ec9-b41a-4436-83d4-c63fda091fbb\" data-root-id=\"bf174fcc-257c-470c-b445-9731bb40e120\" style=\"display: contents;\"></div>\n",
55
+ "</div>\n",
56
+ "<script type=\"application/javascript\">(function(root) {\n",
57
+ " var docs_json = {\"df8c1d01-e046-4a7d-8d56-6a99a583e1d8\":{\"version\":\"3.7.3\",\"title\":\"Bokeh Application\",\"roots\":[{\"type\":\"object\",\"name\":\"panel.models.browser.BrowserInfo\",\"id\":\"bf174fcc-257c-470c-b445-9731bb40e120\"},{\"type\":\"object\",\"name\":\"panel.models.comm_manager.CommManager\",\"id\":\"f45c2a7c-e35c-413c-a3e0-122b08c5cfaa\",\"attributes\":{\"plot_id\":\"bf174fcc-257c-470c-b445-9731bb40e120\",\"comm_id\":\"948abc4a431b4162967a80a3b5aad5ee\",\"client_comm_id\":\"4bba0ca0c35d40d8b83ab7376d066490\"}}],\"defs\":[{\"type\":\"model\",\"name\":\"ReactiveHTML1\"},{\"type\":\"model\",\"name\":\"FlexBox1\",\"properties\":[{\"name\":\"align_content\",\"kind\":\"Any\",\"default\":\"flex-start\"},{\"name\":\"align_items\",\"kind\":\"Any\",\"default\":\"flex-start\"},{\"name\":\"flex_direction\",\"kind\":\"Any\",\"default\":\"row\"},{\"name\":\"flex_wrap\",\"kind\":\"Any\",\"default\":\"wrap\"},{\"name\":\"gap\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"justify_content\",\"kind\":\"Any\",\"default\":\"flex-start\"}]},{\"type\":\"model\",\"name\":\"FloatPanel1\",\"properties\":[{\"name\":\"config\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"contained\",\"kind\":\"Any\",\"default\":true},{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"right-top\"},{\"name\":\"offsetx\",\"kind\":\"Any\",\"default\":null},{\"name\":\"offsety\",\"kind\":\"Any\",\"default\":null},{\"name\":\"theme\",\"kind\":\"Any\",\"default\":\"primary\"},{\"name\":\"status\",\"kind\":\"Any\",\"default\":\"normalized\"}]},{\"type\":\"model\",\"name\":\"GridStack1\",\"properties\":[{\"name\":\"ncols\",\"kind\":\"Any\",\"default\":null},{\"name\":\"nrows\",\"kind\":\"Any\",\"default\":null},{\"name\":\"allow_resize\",\"kind\":\"Any\",\"default\":true},{\"name\":\"allow_drag\",\"kind\":\"Any\",\"default\":true},{\"name\":\"state\",\"kind\":\"Any\",\"default\":[]}]},{\"type\":\"model\",\"name\":\"drag1\",\"properties\":[{\"name\":\"slider_width\",\"kind\":\"Any\",\"default\":5},{\"name\":\"slider_color\",\"kind\":\"Any\",\"default\":\"black\"},{\"name\":\"value\",\"kind\":\"Any\",\"default\":50}]},{\"type\":\"model\",\"name\":\"click1\",\"properties\":[{\"name\":\"terminal_output\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"debug_name\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"clears\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"FastWrapper1\",\"properties\":[{\"name\":\"object\",\"kind\":\"Any\",\"default\":null},{\"name\":\"style\",\"kind\":\"Any\",\"default\":null}]},{\"type\":\"model\",\"name\":\"NotificationArea1\",\"properties\":[{\"name\":\"js_events\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}},{\"name\":\"max_notifications\",\"kind\":\"Any\",\"default\":5},{\"name\":\"notifications\",\"kind\":\"Any\",\"default\":[]},{\"name\":\"position\",\"kind\":\"Any\",\"default\":\"bottom-right\"},{\"name\":\"_clear\",\"kind\":\"Any\",\"default\":0},{\"name\":\"types\",\"kind\":\"Any\",\"default\":[{\"type\":\"map\",\"entries\":[[\"type\",\"warning\"],[\"background\",\"#ffc107\"],[\"icon\",{\"type\":\"map\",\"entries\":[[\"className\",\"fas fa-exclamation-triangle\"],[\"tagName\",\"i\"],[\"color\",\"white\"]]}]]},{\"type\":\"map\",\"entries\":[[\"type\",\"info\"],[\"background\",\"#007bff\"],[\"icon\",{\"type\":\"map\",\"entries\":[[\"className\",\"fas fa-info-circle\"],[\"tagName\",\"i\"],[\"color\",\"white\"]]}]]}]}]},{\"type\":\"model\",\"name\":\"Notification\",\"properties\":[{\"name\":\"background\",\"kind\":\"Any\",\"default\":null},{\"name\":\"duration\",\"kind\":\"Any\",\"default\":3000},{\"name\":\"icon\",\"kind\":\"Any\",\"default\":null},{\"name\":\"message\",\"kind\":\"Any\",\"default\":\"\"},{\"name\":\"notification_type\",\"kind\":\"Any\",\"default\":null},{\"name\":\"_rendered\",\"kind\":\"Any\",\"default\":false},{\"name\":\"_destroyed\",\"kind\":\"Any\",\"default\":false}]},{\"type\":\"model\",\"name\":\"TemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"BootstrapTemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"TemplateEditor1\",\"properties\":[{\"name\":\"layout\",\"kind\":\"Any\",\"default\":[]}]},{\"type\":\"model\",\"name\":\"MaterialTemplateActions1\",\"properties\":[{\"name\":\"open_modal\",\"kind\":\"Any\",\"default\":0},{\"name\":\"close_modal\",\"kind\":\"Any\",\"default\":0}]},{\"type\":\"model\",\"name\":\"ReactiveESM1\",\"properties\":[{\"name\":\"esm_constants\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}}]},{\"type\":\"model\",\"name\":\"JSComponent1\",\"properties\":[{\"name\":\"esm_constants\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}}]},{\"type\":\"model\",\"name\":\"ReactComponent1\",\"properties\":[{\"name\":\"esm_constants\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}}]},{\"type\":\"model\",\"name\":\"AnyWidgetComponent1\",\"properties\":[{\"name\":\"esm_constants\",\"kind\":\"Any\",\"default\":{\"type\":\"map\"}}]},{\"type\":\"model\",\"name\":\"request_value1\",\"properties\":[{\"name\":\"fill\",\"kind\":\"Any\",\"default\":\"none\"},{\"name\":\"_synced\",\"kind\":\"Any\",\"default\":null},{\"name\":\"_request_sync\",\"kind\":\"Any\",\"default\":0}]}]}};\n",
58
+ " var render_items = [{\"docid\":\"df8c1d01-e046-4a7d-8d56-6a99a583e1d8\",\"roots\":{\"bf174fcc-257c-470c-b445-9731bb40e120\":\"a8ba9ec9-b41a-4436-83d4-c63fda091fbb\"},\"root_ids\":[\"bf174fcc-257c-470c-b445-9731bb40e120\"]}];\n",
59
+ " var docs = Object.values(docs_json)\n",
60
+ " if (!docs) {\n",
61
+ " return\n",
62
+ " }\n",
63
+ " const py_version = docs[0].version.replace('rc', '-rc.').replace('.dev', '-dev.')\n",
64
+ " async function embed_document(root) {\n",
65
+ " var Bokeh = get_bokeh(root)\n",
66
+ " await Bokeh.embed.embed_items_notebook(docs_json, render_items);\n",
67
+ " for (const render_item of render_items) {\n",
68
+ " for (const root_id of render_item.root_ids) {\n",
69
+ "\tconst id_el = document.getElementById(root_id)\n",
70
+ "\tif (id_el.children.length && id_el.children[0].hasAttribute('data-root-id')) {\n",
71
+ "\t const root_el = id_el.children[0]\n",
72
+ "\t root_el.id = root_el.id + '-rendered'\n",
73
+ "\t for (const child of root_el.children) {\n",
74
+ " // Ensure JupyterLab does not capture keyboard shortcuts\n",
75
+ " // see: https://jupyterlab.readthedocs.io/en/4.1.x/extension/notebook.html#keyboard-interaction-model\n",
76
+ "\t child.setAttribute('data-lm-suppress-shortcuts', 'true')\n",
77
+ "\t }\n",
78
+ "\t}\n",
79
+ " }\n",
80
+ " }\n",
81
+ " }\n",
82
+ " function get_bokeh(root) {\n",
83
+ " if (root.Bokeh === undefined) {\n",
84
+ " return null\n",
85
+ " } else if (root.Bokeh.version !== py_version) {\n",
86
+ " if (root.Bokeh.versions === undefined || !root.Bokeh.versions.has(py_version)) {\n",
87
+ "\treturn null\n",
88
+ " }\n",
89
+ " return root.Bokeh.versions.get(py_version);\n",
90
+ " } else if (root.Bokeh.version === py_version) {\n",
91
+ " return root.Bokeh\n",
92
+ " }\n",
93
+ " return null\n",
94
+ " }\n",
95
+ " function is_loaded(root) {\n",
96
+ " var Bokeh = get_bokeh(root)\n",
97
+ " return (Bokeh != null && Bokeh.Panel !== undefined)\n",
98
+ " }\n",
99
+ " if (is_loaded(root)) {\n",
100
+ " embed_document(root);\n",
101
+ " } else {\n",
102
+ " var attempts = 0;\n",
103
+ " var timer = setInterval(function(root) {\n",
104
+ " if (is_loaded(root)) {\n",
105
+ " clearInterval(timer);\n",
106
+ " embed_document(root);\n",
107
+ " } else if (document.readyState == \"complete\") {\n",
108
+ " attempts++;\n",
109
+ " if (attempts > 200) {\n",
110
+ " clearInterval(timer);\n",
111
+ "\t var Bokeh = get_bokeh(root)\n",
112
+ "\t if (Bokeh == null || Bokeh.Panel == null) {\n",
113
+ " console.warn(\"Panel: ERROR: Unable to run Panel code because Bokeh or Panel library is missing\");\n",
114
+ "\t } else {\n",
115
+ "\t console.warn(\"Panel: WARNING: Attempting to render but not all required libraries could be resolved.\")\n",
116
+ "\t embed_document(root)\n",
117
+ "\t }\n",
118
+ " }\n",
119
+ " }\n",
120
+ " }, 25, root)\n",
121
+ " }\n",
122
+ "})(window);</script>"
123
+ ]
124
+ },
125
+ "metadata": {
126
+ "application/vnd.holoviews_exec.v0+json": {
127
+ "id": "bf174fcc-257c-470c-b445-9731bb40e120"
128
+ }
129
+ },
130
+ "output_type": "display_data"
131
+ },
132
+ {
133
+ "data": {
134
+ "text/html": [
135
+ "\n",
136
+ "<div class=\"logo-block\">\n",
137
+ "<img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
138
+ "AAAB+wAAAfsBxc2miwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAA6zSURB\n",
139
+ "VHic7ZtpeFRVmsf/5966taWqUlUJ2UioBBJiIBAwCZtog9IOgjqACsogKtqirT2ttt069nQ/zDzt\n",
140
+ "tI4+CrJIREFaFgWhBXpUNhHZQoKBkIUASchWla1S+3ar7r1nPkDaCAnZKoQP/D7mnPOe9/xy76n3\n",
141
+ "nFSAW9ziFoPFNED2LLK5wcyBDObkb8ZkxuaoSYlI6ZcOKq1eWFdedqNzGHQBk9RMEwFAASkk0Xw3\n",
142
+ "ETacDNi2vtvc7L0ROdw0AjoSotQVkKSvHQz/wRO1lScGModBFbDMaNRN1A4tUBCS3lk7BWhQkgpD\n",
143
+ "lG4852/+7DWr1R3uHAZVQDsbh6ZPN7CyxUrCzJMRouusj0ipRwD2uKm0Zn5d2dFwzX1TCGhnmdGo\n",
144
+ "G62Nna+isiUqhkzuKrkQaJlPEv5mFl2fvGg2t/VnzkEV8F5ioioOEWkLG86fvbpthynjdhXYZziQ\n",
145
+ "x1hC9J2NFyi8vCTt91Fh04KGip0AaG9zuCk2wQCVyoNU3Hjezee9bq92duzzTmxsRJoy+jEZZZYo\n",
146
+ "GTKJ6SJngdJqAfRzpze0+jHreUtPc7gpBLQnIYK6BYp/uGhw9YK688eu7v95ysgshcg9qSLMo3JC\n",
147
+ "4jqLKQFBgdKDPoQ+Pltb8dUyQLpeDjeVgI6EgLIQFT5tEl3rn2losHVsexbZ3EyT9wE1uGdkIPcy\n",
148
+ "BGxn8QUq1QrA5nqW5i2tLqvrrM9NK6AdkVIvL9E9bZL/oyfMVd/jqvc8LylzRBKDJSzIExwhQzuL\n",
149
+ "QYGQj4rHfFTc8mUdu3E7yoLtbTe9gI4EqVgVkug2i5+uXGo919ixbRog+3fTbQ8qJe4ZOYNfMoTI\n",
150
+ "OoshUNosgO60AisX15aeI2PSIp5KiFLI9ubb1vV3Qb2ltwLakUCDAkWX7/nHKRmmGIl9VgYsUhJm\n",
151
+ "2NXjKYADtM1ygne9QQDIXlk49FBstMKx66D1v4+XuQr7vqTe0VcBHQlRWiOCbmmSYe2SqtL6q5rJ\n",
152
+ "zsTb7lKx3FKOYC4DoqyS/B5bvLPxvD9Qtf6saxYLQGJErmDOdOMr/zo96km1nElr8bmPOBwI9COv\n",
153
+ "HnFPRIwmkSOv9kcAS4heRsidOkpeWBgZM+UBrTFAXNYL5Vf2ii9c1trNzpYdaoVil3WIc+wdk+gQ\n",
154
+ "noie3ecCcxt9ITcLAPWt/laGEO/9U6PmzZkenTtsSMQ8uYywJVW+grCstAvCIaAdArAsIWkRDDs/\n",
155
+ "KzLm2YcjY1Lv0UdW73HabE9n6V66cxSzfEmuJssTpKGVp+0vHq73FwL46eOjpMpbRAnNmJFrGJNu\n",
156
+ "Ukf9Yrz+3rghiumCKNXXWPhLYcjxGsIpoCMsIRoFITkW8AuyM8jC1+/QLx4bozCEJIq38+1rtpR6\n",
157
+ "V/yzb8eBlRb3fo5l783N0CWolAzJHaVNzkrTzlEp2bQ2q3TC5gn6wpnoQAmwSiGh2GitnTmVMc5O\n",
158
+ "UyfKWUKCIsU7+fZDKwqdT6DDpvkzAX4/+AMFjk0tDp5GRXLpQ2MUmhgDp5gxQT8+Y7hyPsMi8uxF\n",
159
+ "71H0oebujHALECjFKaW9Lm68n18wXp2kVzIcABytD5iXFzg+WVXkegpAsOOYziqo0OkK76GyquC3\n",
160
+ "ltZAzMhhqlSNmmWTE5T6e3IN05ITFLM4GdN0vtZ3ob8Jh1NAKXFbm5PtLU/eqTSlGjkNAJjdgn/N\n",
161
+ "aedXa0tdi7+t9G0FIF49rtMSEgAs1kDLkTPO7ebm4IUWeyh1bKomXqlgMG6kJmHcSM0clYLJ8XtR\n",
162
+ "1GTnbV3F6I5wCGikAb402npp1h1s7LQUZZSMIfALFOuL3UUrfnS8+rez7v9qcold5tilgHbO1fjK\n",
163
+ "9ubb17u9oshxzMiUBKXWqJNxd+fqb0tLVs4lILFnK71H0Ind7uiPgACVcFJlrb0tV6DzxqqTIhUM\n",
164
+ "CwDf1/rrVhTa33/3pGPxJYdQ2l2cbgVcQSosdx8uqnDtbGjh9SlDVSMNWhlnilfqZk42Th2ZpLpf\n",
165
+ "xrHec5e815zrr0dfBZSwzkZfqsv+1FS1KUknUwPARVvItfKUY+cn57yP7qv07UE3p8B2uhUwLk09\n",
166
+ "e0SCOrK+hbdYHYLjRIl71wWzv9jpEoeOHhGRrJAzyEyNiJuUqX0g2sBN5kGK6y2Blp5M3lsB9Qh4\n",
167
+ "y2Ja6x6+i0ucmKgwMATwhSjdUu49tKrQ/pvN5d53ml2CGwCmJipmKjgmyuaXzNeL2a0AkQ01Th5j\n",
168
+ "2DktO3Jyk8f9vcOBQHV94OK+fPumJmvQHxJoWkaKWq9Vs+yUsbq0zGT1I4RgeH2b5wef7+c7bl8F\n",
169
+ "eKgoHVVZa8ZPEORzR6sT1BzDUAD/d9F78e2Tzv99v8D+fLVTqAKAsbGamKey1Mt9Ann4eH3gTXTz\n",
170
+ "idWtAJ8PQWOk7NzSeQn/OTHDuEikVF1R4z8BQCy+6D1aWRfY0tTGG2OM8rRoPaeIj5ZHzJxszElN\n",
171
+ "VM8K8JS5WOfv8mzRnQAKoEhmt8gyPM4lU9SmBK1MCQBnW4KONT86v1hZ1PbwSXPw4JWussVjtH9Y\n",
172
+ "NCoiL9UoH/6PSu8jFrfY2t36erQHXLIEakMi1SydmzB31h3GGXFDFNPaK8Rme9B79Ixrd0WN+1ij\n",
173
+ "NRQ/doRmuFLBkHSTOm5GruG+pFjFdAmorG4IXH1Qua6ASniclfFtDYt+oUjKipPrCQB7QBQ2lrgP\n",
174
+ "fFzm+9XWUtcqJ3/5vDLDpJ79XHZk3u8nGZ42qlj1+ydtbxysCezrydp6ugmipNJ7WBPB5tydY0jP\n",
175
+ "HaVNzs3QzeE4ZpTbI+ZbnSFPbVOw9vsfnVvqWnirPyCNGD08IlqtYkh2hjZ5dErEQzoNm+6ykyOt\n",
176
+ "Lt5/PQEuSRRKo22VkydK+vvS1XEKlhCJAnsqvcVvH7f/ZU2R67eXbMEGAMiIV5oWZWiWvz5Fv2xG\n",
177
+ "sjqNJQRvn3Rs2lji/lNP19VjAQDgD7FHhujZB9OGqYxRkZxixgRDVlqS6uEOFaJUVu0rPFzctrnF\n",
178
+ "JqijImVp8dEKVWyUXDk92zAuMZ6bFwpBU1HrOw6AdhQgUooChb0+ItMbWJitSo5Ws3IAOGEOtL53\n",
179
+ "0vHZih9sC4vtofZ7Qu6523V/fmGcds1TY3V36pUsBwAbSlxnVh2xLfAD/IAIMDf7XYIkNmXfpp2l\n",
180
+ "18rkAJAy9HKFaIr/qULkeQQKy9zf1JgDB2uaeFNGijo5QsUyacNUUTOnGO42xSnv4oOwpDi1zYkc\n",
181
+ "efUc3I5Gk6PhyTuVKaOGyLUAYPGIoY9Pu/atL/L92+4q9wbflRJ2Trpm/jPjdBtfnqB/dIThcl8A\n",
182
+ "KG7hbRuKnb8qsQsVvVlTrwQAQMUlf3kwJI24Z4JhPMtcfng5GcH49GsrxJpGvvHIaeem2ma+KSjQ\n",
183
+ "lIwUdYyCY8j4dE1KzijNnIP2llF2wcXNnsoapw9XxsgYAl6k+KzUXbi2yP3KR2ecf6z3BFsBICdW\n",
184
+ "nvnIaG3eHybqX7vbpEqUMT+9OL4Qpe8VON7dXuFd39v19FoAABRVePbGGuXTszO0P7tu6lghUonE\n",
185
+ "llRdrhArLvmKdh9u29jcFiRRkfLUxBiFNiqSU9icoZQHo5mYBI1MBgBH6wMNb+U7Pnw337H4gi1Y\n",
186
+ "ciWs+uks3Z9fztUvfzxTm9Ne8XXkvQLHNytOOZeiD4e0PgkAIAYCYknKUNUDSXEKzdWNpnil7r4p\n",
187
+ "xqkjTarZMtk/K8TQ6Qve78qqvXurGwIJqcOUKfUWHsm8KGvxSP68YudXq4pcj39X49uOK2X142O0\n",
188
+ "Tz5/u/7TVybqH0rSya6ZBwD21/gubbrgWdDgEOx9WUhfBaC2ibcEBYm7a7x+ukrBMNcEZggyR0TE\n",
189
+ "T8zUPjikQ4VosQZbTpS4vqizBKvqmvjsqnpfzaZyx9JPiz1/bfGKdgD45XB1zoIMzYbfTdS/NClB\n",
190
+ "Gct0USiY3YL/g0LHy/uq/Ef6uo5+n0R/vyhp17Klpge763f8rMu6YU/zrn2nml+2WtH+Z+5IAAFc\n",
191
+ "2bUTdTDOSNa9+cQY7YLsOIXhevEkCvzph7a8laecz/Un/z4/Ae04XeL3UQb57IwU9ZDr9UuKVajv\n",
192
+ "nxp1+1UVIo/LjztZkKH59fO3G/JemqCfmaCRqbqbd90ZZ8FfjtkfAyD0J/9+C2h1hDwsSxvGjNDc\n",
193
+ "b4zk5NfrSwiQblLHzZhg+Jf4aPlUwpDqkQqa9nimbt1/TDH8OitGMaQnj+RJS6B1fbF7SY1TqO5v\n",
194
+ "/v0WAADl1f7zokgS7s7VT2DZ7pegUjBM7mjtiDZbcN4j0YrHH0rXpCtY0qPX0cVL0rv5jv/ZXend\n",
195
+ "0u/EESYBAFBU4T4Qa5TflZOhTe7pmKpaP8kCVUVw1+yhXfJWvn1P3hnXi33JsTN6PnP3hHZ8Z3/h\n",
196
+ "aLHzmkNPuPj7Bc/F/Q38CwjTpSwQXgE4Vmwry9tpfq/ZFgqFMy4AVDtCvi8rvMvOmv0N4YwbVgEA\n",
197
+ "sPM72/KVnzfspmH7HQGCRLG2yL1+z8XwvPcdCbsAANh+xPzstgMtxeGKt+6MK3/tacfvwhWvIwMi\n",
198
+ "oKEBtm0H7W+UVfkc/Y1V0BhoPlDr/w1w/eu1vjIgAgDg22OtX6/eYfnEz/focrZTHAFR+PSs56/7\n",
199
+ "q32nwpjazxgwAQCwcU/T62t3WL7r6/jVRa6/byp1rei+Z98ZUAEAhEPHPc8fKnTU9nbgtnOe8h0l\n",
200
+ "9hcGIqmODLQAHCy2Xti6v/XNRivf43f4fFvIteu854+VHnR7q9tfBlwAAGz+pnndB9vM26UebAe8\n",
201
+ "SLHujPOTPVW+rwY+sxskAAC2HrA8t2Vvc7ffP1r9o+vwR2dcr92InIAbKKC1FZ5tB1tf+/G8p8sv\n",
202
+ "N/9Q5zd/XR34LYCwV5JdccMEAMDBk45DH243r/X4xGvqxFa/GNpS7n6rwOwNWwHVE26oAADYurf1\n",
203
+ "zx/utOzt+DMKYM0p17YtZZ5VNzqfsB2HewG1WXE8PoZ7gOclbTIvynZf9JV+fqZtfgs/8F/Nu5rB\n",
204
+ "EIBmJ+8QRMmpU7EzGRsf2FzuePqYRbzh/zE26EwdrT10f6r6o8HOYzCJB9Dpff8tbnGLG8L/A/WE\n",
205
+ "roTBs2RqAAAAAElFTkSuQmCC'\n",
206
+ " style='height:25px; border-radius:12px; display: inline-block; float: left; vertical-align: middle'></img>\n",
207
+ "\n",
208
+ "\n",
209
+ " <img src='data:image/png;base64,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'\n",
210
+ " style='height:15px; border-radius:12px; display: inline-block; float: left'></img>\n",
211
+ " \n",
212
+ "\n",
213
+ "\n",
214
+ "\n",
215
+ "\n",
216
+ "</div>\n"
217
+ ]
218
+ },
219
+ "metadata": {},
220
+ "output_type": "display_data"
221
+ },
222
+ {
223
+ "data": {
224
+ "text/html": [
225
+ "<script type=\"esms-options\">{\"shimMode\": true}</script><style>*[data-root-id],\n",
226
+ "*[data-root-id] > * {\n",
227
+ " box-sizing: border-box;\n",
228
+ " font-family: var(--jp-ui-font-family);\n",
229
+ " font-size: var(--jp-ui-font-size1);\n",
230
+ " color: var(--vscode-editor-foreground, var(--jp-ui-font-color1));\n",
231
+ "}\n",
232
+ "\n",
233
+ "/* Override VSCode background color */\n",
234
+ ".cell-output-ipywidget-background:has(\n",
235
+ " > .cell-output-ipywidget-background > .lm-Widget > *[data-root-id]\n",
236
+ " ),\n",
237
+ ".cell-output-ipywidget-background:has(> .lm-Widget > *[data-root-id]) {\n",
238
+ " background-color: transparent !important;\n",
239
+ "}\n",
240
+ "</style>"
241
+ ]
242
+ },
243
+ "metadata": {},
244
+ "output_type": "display_data"
245
+ },
246
+ {
247
+ "data": {
248
+ "application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = false;\n const py_version = '3.7.3'.replace('rc', '-rc.').replace('.dev', '-dev.');\n const reloading = true;\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.7.0/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.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));",
249
+ "application/vnd.holoviews_load.v0+json": ""
250
+ },
251
+ "metadata": {},
252
+ "output_type": "display_data"
253
+ },
254
+ {
255
+ "data": {
256
+ "application/javascript": "\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",
257
+ "application/vnd.holoviews_load.v0+json": ""
258
+ },
259
+ "metadata": {},
260
+ "output_type": "display_data"
261
+ }
262
+ ],
263
+ "source": [
264
+ "import matplotlib.pyplot as plt\n",
265
+ "import datashader as ds\n",
266
+ "from holoviews.operation.datashader import datashade, rasterize, inspect_points\n",
267
+ "from bokeh.models import PrintfTickFormatter, FixedTicker\n",
268
+ "import holoviews as hv\n",
269
+ "hv.extension('bokeh')\n",
270
+ "import matplotlib.pyplot as plt\n",
271
+ "import rioxarray\n",
272
+ "import hvplot.xarray\n",
273
+ "import panel as pn"
274
+ ]
275
+ },
276
+ {
277
+ "cell_type": "code",
278
+ "execution_count": 3,
279
+ "id": "16e06e14",
280
+ "metadata": {},
281
+ "outputs": [
282
+ {
283
+ "name": "stdout",
284
+ "output_type": "stream",
285
+ "text": [
286
+ " THICK geometry EAST \\\n",
287
+ "0 2193.7041 b'\\x01\\x01\\x00\\x00\\x00|\\xa8\\xdb*\\xd3\\x830AP\\xf... 1.082323e+06 \n",
288
+ "1 2899.8000 b\"\\x01\\x01\\x00\\x00\\x00<\\xbd@\\xa8J\\xb1$A'&\\x0e\\... 6.780533e+05 \n",
289
+ "2 1819.1100 b'\\x01\\x01\\x00\\x00\\x00h\\x9ez<\\xb3\\x97\\x1eAZ\\xc... 5.012288e+05 \n",
290
+ "3 1124.9400 b'\\x01\\x01\\x00\\x00\\x00\\xaa\\x0c\\xcf{\\xe9r*\\xc1\\... -8.666767e+05 \n",
291
+ "4 2122.4100 b'\\x01\\x01\\x00\\x00\\x00\\x97\\x9b\\xc4h\\xc3\\xe6$\\x... -6.848977e+05 \n",
292
+ "\n",
293
+ " NORTH vx vy v ith_bm smb \\\n",
294
+ "0 1.179464e+05 1.718832 0.091488 1.721265 2225.768378 28.600311 \n",
295
+ "1 -1.755376e+06 0.595385 0.635081 0.870523 2487.617401 83.017294 \n",
296
+ "2 -8.708590e+05 -73.866877 -42.897329 85.419531 1827.670487 21.117418 \n",
297
+ "3 3.561459e+05 -3.913554 -0.195708 3.918445 1130.303771 136.581627 \n",
298
+ "4 6.913987e+04 -1.471376 7.756460 7.894785 2105.888247 108.577022 \n",
299
+ "\n",
300
+ " z s temp gridCellId \n",
301
+ "0 3890.095924 0.004726 221.131235 137 \n",
302
+ "1 2348.626277 0.000567 235.855494 28 \n",
303
+ "2 1771.083276 0.004876 239.003074 82 \n",
304
+ "3 216.134166 0.006954 246.742698 149 \n",
305
+ "4 1400.136807 0.002945 243.399524 132 \n"
306
+ ]
307
+ }
308
+ ],
309
+ "source": [
310
+ "import pandas as pd\n",
311
+ "\n",
312
+ "# Læs en Parquet-fil ind i en DataFrame\n",
313
+ "grid_train = pd.read_parquet(\"grid_300km_30M.parquet\")\n",
314
+ "\n",
315
+ "# Vis de første rækker\n",
316
+ "print(grid_train.head())"
317
+ ]
318
+ },
319
+ {
320
+ "cell_type": "code",
321
+ "execution_count": 5,
322
+ "id": "5fa24d84",
323
+ "metadata": {},
324
+ "outputs": [
325
+ {
326
+ "data": {
327
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAHFCAYAAAAOmtghAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAPQRJREFUeJzt3Xl0VFW+/v+nIKFCIAkyhCQSIIDMgxhUgowiAQIISF8HUBG1L7SISODyFZQmOEErbSO2gLZAGhDRXhEbZGjSQoI20BoGZZKrLYNAIoKSQIBKkZzfH/5S1yKVCSqp1Ob9WitrefbZ55z9qV0mD2eoslmWZQkAAMAQ1Xw9AAAAAG8i3AAAAKMQbgAAgFEINwAAwCiEGwAAYBTCDQAAMArhBgAAGIVwAwAAjEK4AQAARiHcAF6UnJwsm83m8WfKlCkVfvymTZvqkUceuaptbTabkpKSXMtpaWmy2WxKS0vzytgqypEjRzRo0CDVrVtXNptNTz/9tK+HdE0K30NHjhwp97ZJSUmy2Ww6ffp0qX179+6t3r17l3+AgB8I8PUAABMtXbpUrVu3dmuLiory0Wiuzi233KLt27erbdu2vh5KiSZNmqR///vfWrJkiSIiIhQZGenrIV2TQYMGafv27X5fB+BLhBugArRv315dunTx+n4vXLig4OBgr+/Xk9DQUHXt2rVSjnUt9u3bp9tuu03Dhg3z9VCuycWLFxUUFKQGDRqoQYMGvh4O4Ne4LAX4wJo1axQXF6fg4GCFhISoX79+2r59u1ufwksMu3bt0m9+8xvdcMMNat68uSTJ6XRq6tSpioiIUHBwsLp3767PP//c47GysrI0duxYNWrUSDVq1FBMTIxmzZqly5cvlzhGT5elHnnkEdWuXVvffvutEhISVLt2bUVHR2vy5MlyOBxu2x8/fly/+c1vFBISojp16mjUqFH64osvZLPZlJycXOKxf/zxRz3xxBNq27atateurfDwcN1555369NNPi4zv22+/1YYNG1yX/4q7nFP4enr6KelS3kcffSSbzaZPPvmkyLqFCxfKZrPpq6++kiRlZGTo/vvvV9OmTVWzZk01bdpUDzzwgI4ePeq2XeGlp02bNunRRx9VgwYNFBwcLIfD4fGyVGpqqoYOHapGjRopKChILVq00NixY4u9/PT999/rnnvuUWhoqMLCwvTggw/qxx9/LLbGQnl5eXrxxRfVunVr2e12NWjQQGPGjCmybdOmTTV48GBt3LhRt9xyi2rWrKnWrVtryZIlpR4DqAycuQEqQH5+fpHwEBDwy/9uK1eu1KhRoxQfH6/33ntPDodDr7zyinr37q1PPvlE3bt3d9vunnvu0f33369x48YpNzdXkvTb3/5Wy5Yt05QpU9SvXz/t27dP99xzj86dO+e2bVZWlm677TZVq1ZNv//979W8eXNt375dL774oo4cOaKlS5eWuzan06m7775bjz32mCZPnqytW7fqhRdeUFhYmH7/+99LknJzc9WnTx/99NNP+sMf/qAWLVpo48aNuu+++8p0jJ9++kmSNHPmTEVEROj8+fNavXq16zXq3bu367LZ8OHD1bx5c82dO1eSir2c8/jjj2vAgAFubR9++KFeffVVtWvXrtixDB48WOHh4Vq6dKn69u3rti45OVm33HKLOnbsKOmX+39atWql+++/X3Xr1lVmZqYWLlyoW2+9VQcOHFD9+vXdtn/00Uc1aNAgLV++XLm5uQoMDPQ4hv/85z+Ki4vT448/rrCwMB05ckSvvfaaunfvrr179xbZbvjw4br33ns1btw47d+/XzNmzNCBAwf073//u9hjFBQUaOjQofr00081depUdevWTUePHtXMmTPVu3dvZWRkqGbNmq7+X375pSZPnqxnnnlGDRs21DvvvKPHHntMLVq0UM+ePYt9PYFKYQHwmqVLl1qSPP44nU4rPz/fioqKsjp06GDl5+e7tjt37pwVHh5udevWzdU2c+ZMS5L1+9//3u0YBw8etCRZkyZNcmt/9913LUnW6NGjXW1jx461ateubR09etSt79y5cy1J1v79+11tkqyZM2e6lrds2WJJsrZs2eJqGz16tCXJ+uCDD9z2l5CQYLVq1cq1/Oabb1qSrA0bNrj1Gzt2rCXJWrp0qecXsBiXL1+2nE6n1bdvX2v48OFu65o0aWINGjSoXPuzLMv69NNPraCgIGvUqFFWQUFBiX0TExOtmjVrWmfPnnW1HThwwJJkvfHGGyWO+/z581atWrWs119/3dVe+D55+OGHi2xTuO7w4cMe91lQUGA5nU7r6NGjliTr73//u2td4XumuPfGihUrXG29evWyevXq5Vp+7733LElWSkqK27ZffPGFJclasGCBq61JkyZWUFCQ2/vq4sWLVt26da2xY8cW+3oAleW6viy1detWDRkyRFFRUbLZbProo4/KvQ/LsjR37ly1bNlSdrtd0dHRevnll70/WPiVZcuW6YsvvnD7CQgI0KFDh3Ty5Ek99NBDqlbt//73q127tkaMGKEdO3bowoULbvsaMWKE2/KWLVskSaNGjXJrv/fee11nhwp9/PHH6tOnj6KionT58mXXz8CBAyVJ6enp5a7NZrNpyJAhbm0dO3Z0u/SSnp6ukJCQImdKHnjggTIfZ9GiRbrlllsUFBSkgIAABQYG6pNPPtHBgwfLPeYrHTx4UHfffbe6deumJUuWyGazSfq/M26FPwUFBZJ+OcNy8eJFvf/++659LF26VHa7XSNHjnS1nT9/Xv/v//0/tWjRQgEBAQoICFDt2rWVm5vrcdxXzm1xTp06pXHjxik6Otr1WjRp0sRVy5WKe28Uvnc8+fjjj1WnTh0NGTLE7TW4+eabFRERUeSpuZtvvlmNGzd2LQcFBally5ZFLsEBvnBdX5bKzc1Vp06dNGbMmDL/krnSxIkTtWnTJs2dO1cdOnRQdnZ2mR7DhNnatGnj8YbiM2fOSPJ86SQqKkoFBQX6+eef3W4avrJv4T4iIiLc2gMCAlSvXj23th9++EFr164t9lLE1bxXg4ODFRQU5NZmt9t16dIltzE2bNiwyLae2jx57bXXNHnyZI0bN04vvPCC6tevr+rVq2vGjBnXHG5OnjypAQMGqFGjRvrwww9Vo0YN17q+ffu6Bb7Ro0crOTlZ7dq106233qqlS5fqv//7v5Wfn68VK1Zo6NChqlu3rqv/yJEj9cknn2jGjBm69dZbFRoaKpvNpoSEBF28eLHIWMryRFRBQYHi4+N18uRJzZgxQx06dFCtWrVUUFCgrl27etxvce+NwveOJz/88IPOnj3r9nr82pXvlSvfa9Iv7wNP4wEq23UdbgYOHOj6F6wneXl5eu655/Tuu+/q7Nmzat++vf7whz+4Phvi4MGDWrhwofbt26dWrVpV0qjhzwr/IGRmZhZZd/LkSVWrVk033HCDW3vhWYUr95GVlaUbb7zR1X758uUif7zq16+vjh076qWXXvI4nop6PL1evXoeb3DOysoq0/YrVqxQ7969tXDhQrf2K+8pKq+cnBwlJCSooKBA69evV1hYmNv6t956y+0Yv75HZsyYMXriiSd08OBBfffdd8rMzNSYMWNc67Ozs/Xxxx9r5syZeuaZZ1ztDofDdQ/Rla6cW0/27dunL7/8UsnJyRo9erSr/dtvvy12m+LeG54CSaH69eurXr162rhxo8f1ISEhpY4VqCqu63BTmjFjxujIkSNatWqVoqKitHr1ag0YMEB79+7VTTfdpLVr16pZs2b6+OOPNWDAAFmWpbvuukuvvPKK27/mgEKtWrXSjTfeqJUrV2rKlCmuP265ublKSUlxPUFVksJw/e677yo2NtbV/sEHHxS5iXnw4MFav369mjdvXiQ0VaRevXrpgw8+0IYNG9z+AbFq1aoybW+z2WS3293avvrqK23fvl3R0dFXNaa8vDwNHz5cR44c0WeffaZGjRoV6VPSP1IeeOABJSYmKjk5Wd99951uvPFGxcfHu43Zsqwi437nnXeUn59/VWMu3K+kIvt96623it2muPdGSR/aN3jwYK1atUr5+fm6/fbbr3q8QFVAuCnGf/7zH7333ns6fvy461+3U6ZM0caNG7V06VK9/PLL+u6773T06FH97W9/07Jly5Sfn69JkybpN7/5jTZv3uzjClAVVatWTa+88opGjRqlwYMHa+zYsXI4HHr11Vd19uxZzZkzp9R9tGnTRg8++KDmzZunwMBA3XXXXdq3b5/mzp2r0NBQt77PP/+8UlNT1a1bNz311FNq1aqVLl26pCNHjmj9+vVatGiRxz/y12r06NH605/+pAcffFAvvviiWrRooQ0bNugf//iH63UoyeDBg/XCCy9o5syZ6tWrlw4dOqTnn39eMTExpT7CXpxJkyZp8+bNevnll3X+/Hnt2LHDta5Bgwaux+yLU6dOHQ0fPlzJyck6e/aspkyZ4lZHaGioevbsqVdffVX169dX06ZNlZ6ersWLF6tOnTpXNWZJat26tZo3b65nnnlGlmWpbt26Wrt2rVJTU4vd5sMPP1RAQID69evnelqqU6dOuvfee4vd5v7779e7776rhIQETZw4UbfddpsCAwN1/PhxbdmyRUOHDtXw4cOvug6gMhFuirFr1y5ZlqWWLVu6tTscDtep3YKCAjkcDi1btszVb/HixYqNjdWhQ4e4VAWPRo4cqVq1amn27Nm67777VL16dXXt2lVbtmxRt27dyrSPxYsXq2HDhkpOTtb8+fN18803KyUlRffff79bv8jISGVkZOiFF17Qq6++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IcodbnJzc/Xkk08qPDxctWvX1g033OD2Ux4LFy5Udna2evfurcjISNfP+++/7+qTmZmpY8eOuZZjYmK0fv16paWl6eabb9YLL7yg+fPn8xg4AACQdBVPS02dOlVbtmzRggUL9PDDD+vNN9/UiRMn9NZbb2nOnDnl2lcZ7mVWcnJykbZevXpp165d5ToWAAC4PpQ73Kxdu1bLli1T79699eijj6pHjx5q0aKFmjRponfffVejRo2qiHECAACUSbkvS/3000+uG39DQ0Ndj353795dW7du9e7oAAAAyqnc4aZZs2Y6cuSIJKlt27b64IMPJP1yRqdOnTreHBsAAEC5lTvcjBkzRl9++aWkX55kWrBggex2uyZNmqT/+Z//8foAAQAAyqPc99xMmjTJ9d99+vTR119/rYyMDDVv3lydOnXy6uAAAADKq9xnbpYtW+b2XU2NGzfWPffcozZt2mjZsmVeHRwAAEB5XdVlqcJv7/61c+fOacyYMV4ZFAAAwNUqd7ixLMvjl2geP35cYWFhXhkUAADA1SrzPTedO3eWzWaTzWZT3759FRDwf5vm5+fr8OHDGjBgQIUMEgAAoKzKHG6GDRsmSdqzZ4/69++v2rVru9bVqFFDTZs25SsQAACAz5U53MycOVOS1LRpU913330KCgqqsEEBAABcrXI/Cj569GhJUl5enk6dOqWCggK39Y0bN/bOyAAAAK5CucPNN998o0cffVTbtm1zay+80Tg/P99rgwMAACivcoebRx55RAEBAfr4448VGRnp8ckpAAAAXyl3uNmzZ4927typ1q1bV8R4AAAArkm5P+embdu2On36dEWMBQAA4JqVO9z84Q9/0NSpU5WWlqYzZ84oJyfH7QcAAMCXyn1Z6q677pIk9e3b162dG4oBAEBVUO5ws2XLlmLX7d69+5oGAwAAcK3KHW569erltpydna13331X77zzjr788ks9/fTT3hobAABAuZX7nptCmzdv1oMPPqjIyEi98cYbSkhIUEZGhjfHBgAAUG7lOnNz/PhxJScna8mSJcrNzdW9994rp9OplJQUtW3btqLGCAAAUGZlPnOTkJCgtm3b6sCBA3rjjTd08uRJvfHGGxU5NgAAgHIr85mbTZs26amnntLvfvc73XTTTRU5JgAAgKtW5jM3n376qc6dO6cuXbro9ttv15///Gf9+OOP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",
328
+ "text/plain": [
329
+ "<Figure size 640x480 with 1 Axes>"
330
+ ]
331
+ },
332
+ "metadata": {},
333
+ "output_type": "display_data"
334
+ }
335
+ ],
336
+ "source": [
337
+ "import matplotlib.pyplot as plt\n",
338
+ "\n",
339
+ "plt.hist(grid_train['z'], bins=50)\n",
340
+ "plt.xlabel('z')\n",
341
+ "plt.ylabel('Antal')\n",
342
+ "plt.title('Fordeling af z-variablen')\n",
343
+ "plt.grid(True)\n",
344
+ "plt.show()"
345
+ ]
346
+ },
347
+ {
348
+ "cell_type": "code",
349
+ "execution_count": 4,
350
+ "id": "64ac63b9",
351
+ "metadata": {},
352
+ "outputs": [
353
+ {
354
+ "data": {
355
+ "application/vnd.jupyter.widget-view+json": {
356
+ "model_id": "18303e3164d840fca112071c1c51ac16",
357
+ "version_major": 2,
358
+ "version_minor": 0
359
+ },
360
+ "text/plain": [
361
+ "BokehModel(combine_events=True, render_bundle={'docs_json': {'3d01d759-610b-4eb6-a863-44901ffb7721': {'version…"
362
+ ]
363
+ },
364
+ "metadata": {},
365
+ "output_type": "display_data"
366
+ }
367
+ ],
368
+ "source": [
369
+ "points_bedmap_predicted = hv.Points(grid_train, ['EAST', 'NORTH'], 'THICK') # HoloViews Points object\n",
370
+ "\n",
371
+ "formatter = PrintfTickFormatter(format='%i')\n",
372
+ "\n",
373
+ "# Rasterize the points\n",
374
+ "rasterized_bedmap_predicted = rasterize(points_bedmap_predicted,aggregator=ds.mean('THICK')).opts(\n",
375
+ " cmap=plt.colormaps['turbo'],\n",
376
+ " cnorm='eq_hist',\n",
377
+ " width=700,\n",
378
+ " height=700,\n",
379
+ " colorbar=True,\n",
380
+ " xaxis=None, # Remove x-axis\n",
381
+ " yaxis=None, # Remove y-axis\n",
382
+ " colorbar_opts={\n",
383
+ " 'title': 'Ice Thickness measurements [m]',\n",
384
+ " 'formatter': formatter, # Apply custom formatter to the colorbar,\n",
385
+ " \"ticker\": FixedTicker(ticks=[500, 1000, 1500, 2000, 2500, 3000, 4500])\n",
386
+ " },\n",
387
+ " colorbar_position='bottom',\n",
388
+ ")\n",
389
+ "\n",
390
+ "\n",
391
+ "# Display the plot\n",
392
+ "hv.output(rasterized_bedmap_predicted)"
393
+ ]
394
+ },
395
+ {
396
+ "cell_type": "code",
397
+ "execution_count": null,
398
+ "id": "66adcf05",
399
+ "metadata": {},
400
+ "outputs": [],
401
+ "source": [
402
+ "import pandas as pd\n",
403
+ "import numpy as np\n",
404
+ "from scipy.ndimage import maximum_filter, label\n",
405
+ "from scipy.spatial import cKDTree\n",
406
+ "\n",
407
+ "# Lav grid til 2D-array (kræver at EAST/NORTH danner regelmæssigt gitter)\n",
408
+ "# Her antager vi forenklet at data kan reshapes\n",
409
+ "z = grid_train['z'].values.reshape((n_rows, n_cols)) # Du skal bestemme n_rows og n_cols\n",
410
+ "z_max = maximum_filter(z, size=15) # Juster 'size' alt efter opløsning\n",
411
+ "\n",
412
+ "# Find koordinater for lokale maxima\n",
413
+ "local_maxima_mask = (z == z_max)\n",
414
+ "local_max_coords = np.column_stack(np.where(local_maxima_mask)) # row, col\n",
415
+ "\n",
416
+ "# Konvertér til EAST/NORTH\n",
417
+ "east_grid = grid_train['EAST'].values.reshape((n_rows, n_cols))\n",
418
+ "north_grid = grid_train['NORTH'].values.reshape((n_rows, n_cols))\n",
419
+ "mountain_points = np.column_stack([\n",
420
+ " east_grid[local_max_coords[:, 0], local_max_coords[:, 1]],\n",
421
+ " north_grid[local_max_coords[:, 0], local_max_coords[:, 1]]\n",
422
+ "])\n",
423
+ "\n",
424
+ "# KDTree for bjergtoppe\n",
425
+ "tree = cKDTree(mountain_points)\n",
426
+ "\n",
427
+ "# Beregn afstande for alle punkter i datasættet\n",
428
+ "all_points = np.column_stack([grid_train['EAST'], grid_train['NORTH']])\n",
429
+ "distances, _ = tree.query(all_points)\n",
430
+ "\n",
431
+ "# Gem i datasættet\n",
432
+ "grid_train['distance_to_peak'] = distances\n"
433
+ ]
434
+ }
435
+ ],
436
+ "metadata": {
437
+ "kernelspec": {
438
+ "display_name": "appml",
439
+ "language": "python",
440
+ "name": "python3"
441
+ },
442
+ "language_info": {
443
+ "codemirror_mode": {
444
+ "name": "ipython",
445
+ "version": 3
446
+ },
447
+ "file_extension": ".py",
448
+ "mimetype": "text/x-python",
449
+ "name": "python",
450
+ "nbconvert_exporter": "python",
451
+ "pygments_lexer": "ipython3",
452
+ "version": "3.12.9"
453
+ }
454
+ },
455
+ "nbformat": 4,
456
+ "nbformat_minor": 5
457
+ }