swimtracker-firmware/python-mock/PeakDetectionAnalysis.ipynb

991 lines
93 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib notebook\n",
"from measurement_session import *\n",
"from peak_detection import *\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Peak Detection Algorithm Comparison"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"{'sessionStartTime': 1589401905,\n",
" 'startIndex': 0,\n",
" 'values': array([15, 15, 15, ..., 18, 17, 16], dtype=int16)}"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"session_file = '/home/martin/Downloads/1589401905 (1).st'\n",
"session = load_session_from_file(session_file)\n",
"#session = prune_overflown_session(session)\n",
"#session = prune(session, 10, 50)\n",
"session"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [],
"source": [
"#values[8000:8005]"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support.' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('<div/>');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" if (mpl.ratio != 1) {\n",
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
" }\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" fig.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('<div/>');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('<canvas/>');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var backingStore = this.context.backingStorePixelRatio ||\n",
"\tthis.context.webkitBackingStorePixelRatio ||\n",
"\tthis.context.mozBackingStorePixelRatio ||\n",
"\tthis.context.msBackingStorePixelRatio ||\n",
"\tthis.context.oBackingStorePixelRatio ||\n",
"\tthis.context.backingStorePixelRatio || 1;\n",
"\n",
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband = $('<canvas/>');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width * mpl.ratio);\n",
" canvas.attr('height', height * mpl.ratio);\n",
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('<button/>');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('<span/>');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('<span/>');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option)\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(el){\n",
" var fig = this\n",
" el.on(\"remove\", function(){\n",
"\tfig.close_ws(fig, {});\n",
" });\n",
"}\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABIsAAANoCAYAAABA+GrMAAAgAElEQVR4nOzdX4yc13kf4Klsy5RN2W3jWHLcRuQSbf60MNnCrlsXsXTZwLHQAGmri8YFShRJLope1IW40oUhTrCR2hKpKruAMIFFNHUcFI2EcjlrmAHSYuTKAIGklMzdUHIGTVbosq0baZoSw9LcmdOLNQdaLXd35szsfud753mA94K7PHt+fA94BufM7EwjAQAAAMAPNKoOAAAAAEA5XBYBAAAAMOKyCAAAAIARl0UAAAAAjLgsAgAAAGDEZREAAAAAIy6LAAAAABhxWQQAAADAiMsiAAAAAEZcFgEAAAAw4rIIAAAAgBGXRQAAAACMuCwCAAAAYMRlEQAAAAAjLosAAAAAGHFZBAAAAMCIyyIAAAAARlwWAQAAADDisggAAACAEZdFAAAAAIy4LAIAAABgxGURAAAAACMuiwAAAAAYcVkEAAAAwIjLIgAAAABGXBYBAAAAMOKyCAAAAIARl0UAAAAAjLgsAgAAAGDEZREAAAAAIy6LAAAAABhxWQQAAADAiMsiAAAAAEZcFgEAAAAw4rIIAAAAgBGXRQAAAACMuCwCAAAAYMRlEQAAAAAjLosAAAAAGHFZBAAAAMCIyyIAAAAARlwWAQAAADDisggAAACAEZdFAAAAAIy4LAIAAABgxGURAAAAACMuiwAAAAAYcVkEAAAAwIjLIgAAAABGXBYBAAAAMOKyCAAAAIARl0UAAAAAjLgsAgAAAGDEZREAAAAAIy6LAAAAABhxWQQAAADAiMsiAAAAAEZcFgEAAAAw4rIIAAAAgBGXRQAAAACMuCwCAAAAYMRlEQAAAAAjLosAAAAAGHFZBAAAAMCIyyIAAAAARlwWAQAAADDisggAAACAEZdFAAAAAIy4LAIAAABgxGURAAAAACMuiwAAAAAYcVkEAAAAwIjLIgAAAABGXBYBAAAAMOKyCAAAAIARl0UAAAAAjLgsAgAAAGDEZREAAAAAIy6LAAAAABhxWQQAAADAiMsiAAAAAEZcFgEAAAAw4rIIAAAAgBGXRQAAAACMuCwCAAAAYMRlEQAAAAAjLosAAAAAGHFZBAAAAMCIyyIAAAAARlwWAQAAADDisggAAACAEZdFAAAAAIy4LAIAAABgxGURAAAAACMuiwAAAAAYcVkEAAAAwIjLIgAAAABGXBYBAAAAMOKyCAAAAIARl0UAAAAAjLgsAgAAAGDEZRHZBoNBunXrVrp161a6fft22tzcVEoppZRSSik1R3X79u3RuXAwGFR9TGVGXBaR7datW6nRaCillFJKKaWUUunWrVtVH1OZEZdFZHNZpJRSSimllFLqTrksisNlEdlu3769bVOo+uWPSimllFJKKaUOt975IoLbt29XfUxlRlwWkW1zc3O0KWxublYdBwAAgEPmXBiTyyKy2RQAAADmm3NhTC6LyGZTAAAAmG/OhTG5LCKbTQEAAGC+ORfG5LKIbDYFAACA+eZcGJPLIrLZFAAAAOabc2FMLovIZlMAAACYb86FMbksIptNAQAAYL45F8bksohsNgUAAID55lwYk8sistkUAAAA5ptzYUwui8hmUwAAAJhvzoUxuSwim00BAABgvjkXxuSyiGw2BQAAgPnmXBiTyyKy2RQAAADmm3NhTC6LyGZTAAAAmG/OhTG5LCKbTQEAAGC+ORfG5LKIbDYFAACA+eZcGJPLIrLZFAAAAOabc2FMLovIZlMAAACYb86FMbksIptNAQAAYL45F8bksqgQ/+k//afRf7C96sknn9zz53z/+99Pzz77bPr0pz+d/vSf/tPpAx/4QPrxH//x9M/+2T9L3/ve92aa2aYAAAAw35wLY3JZVIh3XhY98MADu9bTTz+968/o9XrpU5/61Ojn3HvvvemDH/zg6M8//MM/nK5cuTKzzDYFAACA+eZcGJPLokK887Io1+c///nUaDTS0aNH06//+q+n27dvp5RSeuWVV9Jf+At/ITUajfTxj388/cmf/MlMMtsUAAAA5ptzYUwuiwox7WXR7/zO74zG//qv//qO77/xxhvp/e9/f2o0GulLX/rSlGm32BQAAADmm3NhTC6LCjHtZdEXvvCF1Gg00rFjx9JgMLjr3/n5n//50d+ZBZvC9DZ6/dTqdNNSey21Ot200esf+Ngq5pQ33pzyxptT3nhzyhtvTnnjzSlvvDmrylsl58KYXBYVYtrLoo997GOp0WikX/qlX9r17/zmb/7maI433ngjN+qITSHf5mCYmsuraWGxnR56/OKoFhbbqbm8mjYHw5mPrWJOeePNKW+8OeWNN6e88eaUN96c8sabs6q8JXAujMllUSHeeVn0mc98Jn3oQx9K9957b/qRH/mR9PnPfz59/etf3/U/3h//8R+Pxn7lK1/ZdY6rV6+O/t6LL744dWabQr7m8uq2B4J3V3N5deZjq5hT3nhzyhtvTnnjzSlvvDnljTenvPHmrCpvCZwLY3JZVIh3XhY1Go30oQ99KN13333bvvY3/+bfTP/zf/7PHWNfe+210d/5j//xP+46R6/XG/29L3/5y2Pl2tzc3LVu3bplU8iw0evveNbg3bWw2E7XezdnNraKOeWNN6e88eaUN96c8sabU954c8obb86q8pbCZVFMLosK8V//639N//Sf/tP07W9/O924cWP09d///d9Pv/ALvzD6z/fJT35yx3/A//Jf/svo+7/927+96xzf//73R39vaWlprFzvvKzaq2wK42t1uns+GNypVqc7s7FVzClvvDnljTenvPHmlDfenPLGm1PeeHNWlbcULoticllUE//8n//z0X/AF154Ydv3xr0sun379ujv/cqv/MpY87osmr2l9tpYDwhLK2szG1vFnPLGm1PeeHPKG29OeePNKW+8OeWNN2dVeUvhsigml0U1MRgM0p//838+NRqN9Oijj277nl9Dq5e6PWMhb5l59SheXj2Kl1eP4uXVo3h59She3nnqUSlcFsXksqhGfu7nfi41Go30l/7SX9r29Xe+wfW/+Tf/Ztfx3uC6DHX7XWh5y8yrR/Hy6lG8vHoUL68excurR/HyzlOPSuFcGJPLohrZ7bIopZQ+9rGPpUajkX7pl35p1/G/+Zu/OfpP/MYbb0ydx6aQr26fsiBvmXn1KF5ePYqXV4/i5dWjeHn1KF7eeepRCZwLY3JZVBODwSD96I/+aGo0GulnfuZndnz/C1/4Qmo0Gun48eNpOBze9Wfc+TvHjh2bSSabQr7NwTA1l1d3PIuwsNhOzeXVtDm4+xpOM7aKOeWNN6e88eaUN96c8sabU954c8obb86q8pbAuTAml0WF2O2C545f/dVfHf0H/LVf+7Ud3/+d3/md0fe/9rWv7fj+H/zBH6QjR46kRqORvvSlL80ks01hetd7N1Or001LK2up1elO9PLS3LFVzClvvDnljTenvPHmlDfenPLGm1PeeHNWlbdKzoUxuSwqxI/92I+lf/kv/2VaXV3d9h/sjTfeSP/4H//j9Kf+1J9KjUYjnTp1Kt2+ffuuP+Pzn/98ajQa6f77709f+9rXRj/n29/+dvqLf/EvpkajkX7k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eHn1KF5ePdp/bCmcC2NyWUQ2m0K+On0qRN3y1u1TLKypNdWjGHn1KF5ePYqXV4/i5Z33HpXCuTAml0Vksynk2xwM01MXrqZjd3kgOPb4xXR2eTVtDoYzG1fV2KrmbC6v7voMzcJiOzULy2tNrek89qhuefUoXl49ipdXj+Ll1aP9x5bAuTAml0VksylM73rvZjp36Vp67PlX0mPPfzudu/T6WC8vzR1X1diq5mx1uunJl15Lp89fTk++9J3U6nSLzmtN9x9nTfcfV7ce1S2vHsXLq0fx8upRvLx6VDbnwphcFpHNpgAAADDfnAtjcllENpsCAADAfHMujMllEdlsCtPZ6PVTq9NNT7y49fLWJ158LbU63bTR6x/42HPfvPPy1lfSuUvXip2zbnmtqTWte15rGi+vNY2X15rGy2tN4+U97DWtmnNhTC6LyGZTyDPtG+cd9pvu1e2N/urYo7rltabWtI55rak1rXtea2pN65jXmh7smpbCuTAml0VksynkOeiP5JxmbClz1i2vNbWm0fNa03h5rWm8vNY0Xl5rGi/vrNe0FM6FMbksIptNYXIbvX5aWGyP9SC0sNje9ukH047d7RmSbePOVD9n3fJaU2ta97zW1JrWMa81taZ1z2tNreksxpbCuTAml0VksylMrtXpjvUAdKdane6hj616zrrltabWdF7yWtN4ea1pvLzWNF5eaxov76zWtCTOhTG5LCKbTWFyS+21iR6EllbWDn1s1XPWLa81tabzkteaxstrTePltabx8lrTeHlntaYlcS6MyWUR2WwKk/MMy/7j6pbXmlrTeclrTePltabx8lrTeHmtaby8XllEXbgsIptNYXJ+d3v/OeuW15pa07rntabWtI55rak1rXtea2pNZzG2FM6FMbksIptNIY9Phdh/XN3yWlNrGj2vNY2X15rGy2tN4+W1pvHy+jQ06sRlEdlsCnk2B8PUXF7d9RmEhcV2ai6vps3BcOZjn7pwNR27y7hjj19MZwuas255rak1rXtea2pN65jXmlrTuue1ptZ0FmNL4FwYk8sistkUpnO9dzO1Ot305EuvpdPnL6cnX/pOanW6Y728dNqx5y5dS489/0p67Plvp3OXXi92zrrltabWtO55rWm8vNY0Xl5rGi+vNY2X97DXtGrOhTG5LCKbTQEAAGC+ORfG5LKIbDaF6Wz0+qnV6aYnXtx6xuKJF19LrU43bfT6Bz723DfvPGPxSjp36dqhzJkzVo/i5dWjeHn1KF5ePYqXV4/i5dWjeHmnmbNqzoUxuSwim00hz7z97nbOWD2Kl1eP4uXVo3h59SheXj2Kl1eP4uWdZs5SOBfG5LKIbDaFPM1lnwqx31g9ipdXj+Ll1aN4efUoXl49ipdXj+LlnWbOUjgXxuSyiGw2hclt9PppYbE91gPCwmJ72xvaTTt2t2crto07M9s5c8bqUby8ehQvrx7Fy6tH8fLqUby8ehQv7zRzlsS5MCaXRWSzKUyu1emO9WBwp1qd7qGPrWLOd47Vo3h59SheXj2Kl1eP4uXVo3h59She3mnmLIlzYUwui8hmU5jcUnttogeEpZW1Qx9bxZzvHKtH8fLqUby8ehQvrx7Fy6tH8fLqUby808xZEufCmFwWkc2mMDnPsOw/Vo/i5dWjeHn1KF5ePYqXV4/i5dWjeHm9soiSuSwim01hcn53e/+xehQvrx7Fy6tH8fLqUby8ehQvrx7Fy+s9iyiZyyKy2RTy+FSI/cfqUby8ehQvrx7Fy6tH8fLqUby8ehQvr09Do1Qui8hmU8izORim5vLqrs94LCy2U3N5NW0OhjMf+9SFq+nYXcYde/xiOntAc+aM1aN4efUoXl49ipdXj+Ll1aN4efUoXt5p5iyFc2FMLovIZlOYzvXezdTqdNOTL72WTp+/nJ586Tup1emO9fLSaceeu3QtPfb8K+mx57+dzl16/VDmzBmrR/Hy6lG8vHoUL68excurR/Hy6lG8vNPMWTXnwphcFpHNpgAAADDfnAtjcllENpvCdDZ6/dTqdNMTL249e/DEi6+lVqebNnr9AxtbxZzyxptT3nhzyhtvTnnjzSlvvDnljTdnVXmr5lwYk8sistkU8tTtd6HlLTOvHsXLq0fx8upRvLx6FC+vHsXLO089KoVzYUwui8hmU8jTXK7XpyzIW2ZePYqXV4/i5dWjeHn1KF5ePYqXd556VArnwphcFpHNpjC5jV4/LSy2x3pAWFhsb3tDu9yxVcwpb7w55Y03p7zx5pQ33pzyxptT3nhzVpW3JM6FMbksIptNYXKtTnesB4M71ep0px5bxZzyxptT3nhzyhtvTnnjzSlvvDnljTdnVXlL4lwYk8sistkUJrfUXpvoAWFpZW3qsVXMKW+8OeWNN6e88eaUN96c8sabU954c1aVtyTOhTG5LCKbTWFydXvGQt4y8+pRvLx6FC+vHsXLq0fx8upRvLzz1KOSOBfG5LKIbDaFydXtd6HlLTOvHsXLq0fx8upRvLx6FC+vHsXLO089KolzYUwui8hmU8hTt09ZkLfMvHoUL68excurR/Hy6lG8vHoUL+889agUzoUxuSwim00hz+ZgmJrLq+n4mbs/ECwstlNzeTVtDoYzG1vFnPLGm1PeeHPKG29OeePNKW+8OeWNN2dVeUvhXBiTyyKy2RSmc713M7U63fTkS6+l0+cvpydf+k5qdbpjvbw0d2wVc8obb055480pb7w55Y03p7zx5pQ33pxV5a2ac2FMLovIZlMAAACYb86FMbksIptNYTobvX5qdbrpiRe3nj144sXXUqvTTRu9/oGNvTNuqb2Wzn3zWjp36Vpaaq9NNDZ6Xj2Kl1eP4uXVo8PJq0fx8upRvLx6FC9vzpxVcy6MyWUR2WwKear8Xei9Pm2hpN/7riKvHsXLq0fx8urR4eTVo3h59SheXj2Kl9d7FlEal0VksynkaS6X+ykL04yte149ipdXj+Ll1aMy8upRvLx6FC+vHsXLe7c5S+FcGJPLIrLZFCa30evv+SzHO2thsb3tDe1yx04ybpqxdc6rR/Hy6lG8vHpUTl49ipdXj+Ll1aN4ed89Z0mcC2NyWUQ2m8LkWp3u2A9eDz1+MbU63anHTjpumrF1zatH8fLqUby8elRWXj2Kl1eP4uXVo3h53zlnSZwLY3JZRDabwuSW2msTPSAsraxNPXbScdOMrWtePYqXV4/i5dWjsvLqUby8ehQvrx7Fy/vOOUviXBiTyyKy2RQmV4dnLKYZW9e8ehQvrx7Fy6tHZeXVo3h59SheXj2Kl9crizhMLovIZlOYXOm/Cz3N2Drn1aN4efUoXl49KievHsXLq0fx8upRvLzes4jD5rKIbDaFPCV/ysI0Y+ueV4/i5dWjeHn1qIy8ehQvrx7Fy6tH8fL6NDQOm8sistkU8mwOhqm5vJqOn7n7A8HCYjs1l1fT5mA4s7F3xu31zMV+Y6Pn1aN4efUoXl49Opy8ehQvrx7Fy6tH8fLmzFkK58KYXBaRzaYwneu9m6nV6aYnX3otnT5/OT350ndSq9Md6+WluWPvjFtaWUvnLl1L5y69npZW1iYaGz2vHsXLq0fx8urR4eTVo3h59SheXj2Klzdnzqo5F8bksohsNgUAAID55lwYk8sistkUAAAA5ptzYUwui8hmU5jORq+/9dLY9lo6981r6dyla2mpvfXS2I1ef6yxT7y49TLVJ158baJxdZtT3nhzyhtvTnnjzSlvvDnljTdn9Lx6NN7YqjkXxuSyiGw2hTzz8qaws79qltoAACAASURBVJhT3nhzyhtvTnnjzSlvvDnljTdn9Lx6NN7YUjgXxuSyiGw2hTzN5fn4uOnDmFPeeHPKG29OeePNKW+8OeWNN2fd8+rReGNL4VwYk8sistkUJrfR6+/5rMG7a2GxPfoEhEnG5o6r25zyxptT3nhzyhtvTnnjzSlvvDnrnFePxhtbEufCmFwWkc2mMLlWpzv2g8GdanW6WWNzx9VtTnnjzSlvvDnljTenvPHmlDfenHXNq0fjjS2Jc2FMLovIZlOY3FJ7beIHhKWVtayxuePqNqe88eaUN96c8sabU954c8obb8665tWj8caWxLkwJpdFZLMpTC76sx1VP8Mib4w55Y03p7zx5pQ33pzyxpuzrnn1aLyxJXEujMllEdlsCpOL/HvUJfzutrz1n1PeeHPKG29OeePNKW+8OeucV4/GG1sS58KYXBYV7uzZs6P/eI3G3st148aN1Gw208mTJ9P999+fjh49mk6ePJnOnj2bbty4MfNsNoU8UT+hoZRPhZC33nPKG29OeePNKW+8OeWNN2fd8+rReGNL4VwYk8uigl29ejXde++9Y10Wra+vpxMnToz+3pEjR9KRI0dGfz5x4kRaX1+faT6bQp7NwTA1l1f3fBZhYbGdmsuraXMwvOvY42fyxtVtTnnjzSlvvDnljTenvPHmlDfenNHz6tF4Y0vhXBiTy6JCbW5upk996lOp0Wikv/E3/sael0Wbm5vp1KlTqdFopAceeCCtrKyk4XCYhsNharfb6aMf/WhqNBrp1KlTM/3Pa1OYzvXezdTqdNPSylo6d+laOnfp9bS0spZane6+Ly+9M/bJl15Lp89fTk++9J2JxtVtTnnjzSlvvDnljTenvPHmlDfenNHz6tF4Y6vmXBiTy6JCPfPMM6nRaKS///f/fvrSl76052XRV7/61dH3O53Oju93Op3R91944YWZZbQpAAAAzDfnwphcFhXo2rVr6ciRI+kjH/lI+t73vrfvZdFnP/vZ1Gg00sMPP7zrz/ypn/qp1Gg00iOPPDKznDaF6Wz0+lvPHrTX0rlvXkvnLl1LS+2tZw82ev2Zj6tqbNV5n3hx6xmhJ158TY+C5LWmMfLqUby8ehQvrx7Fy6tHMfNWzbkwJpdFhRkMBukzn/lMajQa6d/9u3+XUkp7Xhb1+/10zz33pEajkZ555pldf+7TTz+dGo1Ges973pP6/dlsNjaFPHX93e265a3D75pX3aO65bWmMfLqUby8ehQvrx7Fy6tHMfOWwrkwJpdFhfnVX/3V1Gg00k//9E+PvrbXZdHv/u7vjr7Xbrd3/bkXL14c/b3f+73fm0lWm0Ke5nLMT4WoW149ipdXj+qRV4/i5dWjeHn1KF5ePYqZtxTOhTG5LCrIH/zBH6QPfOAD6ejRo+mP/uiPRl/f67LowoULo++9+uqru/7sK1eujP7exYsXx860ubm5a926dcumMKGNXn/PZw3eXQuL7XS9dzN73DRzRs+rR/Hy6lH5efUoXl49ipdXj+Ll1aOYeUvisigml0WFGA6H6ZFHHkmNRiM9++yz276312XR1772tdH3vvvd7+768994443R3/uN3/iNsXPdGbNf2RTG0+p0x34wuFOtTjd73DRzzkNePYqXV4/KzqtH8fLqUby8ehQvrx7FzFsSl0UxuSwqxFe+8pXUaDTSX//rfz0NBoNt35v1ZdHXv/71sXO5LJqtpfbaxA8ISytr2eOmmXMe8upRvLx6VHZePYqXV4/i5dWjeHn1KGbekrgsisllUQH+8A//MB09ejS9733vS9/5znd2fN+vocVRt2csoufVo3h59ajsvHoUL68excurR/Hy6lHMvCVxWRSTy6IC/O2//bdTo9FIX/ziF9P//b//d0ctLi6O/vPd+dr/+3//L6W0/Q2uV1ZWdp3DG1yXoW6/Cx05rx7Fy6tH5efVo3h59SheXj2Kl1ePYuYtiXNhTC6LCnDy5Mmxf93rTv2Df/APUkop9fv9dM8996RGo5GeeeaZXed4+umnU6PRSO95z3tSv9+fSW6bQp66fcpC1Lx6FC+vHtUjrx7Fy6tH8fLqUby8ehQzbymcC2NyWVSAaS6LUkrps5/9bGo0Gunhhx/edY47f+eRRx6ZWW6bQp7NwTA1l1f3fBZhYbGdmsuraXMwnHpcVWOrznv8jB5Fy2tNY+TVo3h59SheXj2Kl1ePYuYthXNhTC6LamCv9yxKKaWvfvWro+9/61vf2vH9b33rW6Pvv/DCCzPLZVOYzvXezdTqdNPSylo6d+laOnfp9bS0spZane6eLy/NHVfV2KrzPvnSa+n0+cvpyZe+o0dB8lrTGHn1KF5ePYqXV4/i5dWjmHmr5lwYk8uiGtjvsmhzczOdOnUqNRqN9OCDD6ZvfOMbaTgcpuFwmL7xjW+kBx98MDUajXTq1KmZ/ue1KQAAAMw358KYXBbVwH6XRSmltL6+nk6cODH6e/fdd1+67777Rn8+ceJEWl9fn2kum8J0Nnr9rWcP2mvp3DevpXOXrqWl9tazBxu93d9XKnfcrOZsdbrpyvpb2/4s7+zy6lG8vHoUL68excurR/Hy6lG8vHpULufCmFwW1cA4l0UppXTjxo109uzZdPLkyXT06NF09OjR9IlPfCI99dRT6caNGzPPZVPIU6ffhR5nnLzWVN7y55TXmspb/pzyWlN5y5+zpLwlcS6MyWUR2WwKeZrL9fmUhUnGyRtvTnnjzSlvvDnljTenvPHmlDfenCXkLYlzYUwui8hmU5jcRq+/77MV76yFxXa63ruZPe4w55Q33pzyxptT3nhzyhtvTnnjzSlvvDmrzlsa58KYXBaRzaYwuVanO9GD0EOPX0ytTjd73GHPKW+8OeWNN6e88eaUN96c8sabU954c1aZtzTOhTG5LCKbTWFyS+21iR8QllbWsscd9pzyxptT3nhzyhtvTnnjzSlvvDnljTdnlXlL41wYk8sistkUJucZFnnrNqe88eaUN96c8sabU954c8obb84q85bGuTAml0VksylMzu9uy1unOeWNN6e88eaUN96c8sabU954c1adtzTOhTG5LCKbTSGPT4WQty5zyhtvTnnjzSlvvDnljTenvPHmLCFvSZwLY3JZRDabQp7NwTA1l1f3fBZhYbGdmsuraXMwnHrcQc8przWVt/w55bWm8pY/p7zWVN7y5ywpb0mcC2NyWUQ2m8J0rvduplanm5ZW1tK5S9fSuUuvp6WVtdTqdPd8eWnuuFnN2ep006tvvr3tz/LOLq8excurR/Hy6lG8vHoUL68excurR+VyLozJZRHZbAoAAADzzbkwJpdFZLMp5Nvo9beeOWhvPVtwZf2tbX/e6PUPfOy5b15L5y5dK3bOuuW1ptY0Sl5rGi+vNY2X15rGy2tN4+U9rDUtgXNhTC6LyGZTmNxB/y70rH+Pum6/ux2xR3XLa03j5bWm8fJa03h5rWm8vNY0Xl7vWUTduCwim01hcs3lw/mUhWnGVj1n3fJaU2s6L3mtaby81jReXmsaL681jZd3VmtaEufCmFwWkc2mMJmNXn/fZyreXQuL7XS9d/NQx1Y5Z06f5qVHdctrTePltabx8lrTeHmtaby81jRe3lmsaWmcC2NyWUQ2m8JkWp3uRA9Ad6rV6R762KrmzO3TvPSobnmtaby81jReXmsaL681jZfXmsbLO+2alsa5MCaXRWSzKUxmqb2W9SC0tLJ26GOrmjO3T/PSo7rltabx8lrTeHmtaby81jReXmsaL++0a1oa58KYXBaRzaYwGc+w7D8ut0/z0qO65bWm8fJa03h5rWm8vNY0Xl5rGi+vVxZRBy6LyGZTmIzf3d5/XE6f5qVHdctrTePltabx8lrTeHmtaby81jReXu9ZRF24LCKbTWFyPhVi/3F1y2tNrem85LWm8fJa03h5rWm8vNY0Xl6fhkZduCwim01hcpuDYWour+77DMLCYjs1l1fT5mB4aGNLmbNuea2pNY2e15rGy2tN4+W1pvHyWtN4eWe9piVxLozJZRHZbAr5rvduplanm5ZW1lKr002vvvn2tj/v9fLSWY09d+laOnfp9WLnrFtea2pNo+S1pvHyWtN4ea1pvLzWNF7ew1rTEjgXxuSyiGw2BQAAgPnmXBiTyyKy2RTybfT6W88ctLeeLbiy/ta2P2/0+gc+9tw3r6Vzl64d6pyTjNWjeHn1KF5ePYqXV4/i5dWjeHn1KF7eaeYsgXNhTC6LyGZTmJzf3d5/rB7Fy6tH8fLqUby8ehQvrx7Fy6tH8fJOM2dJnAtjcllENpvC5JrLPhViv7F6FC+vHsXLq0fx8upRvLx6FC+vHsXLO82cJXEujMllEdlsCpPZ6PX3fdbg3bWw2E7XezcPdWwVc94Z++r623oULK81jZfXmsbLa03j5bWm8fJa03h5p1nT0jgXxuSyiGw2hcm0Ot2JHgzuVKvTPfSxVcz50OMX0+nzl/UoWF5rGi+vNY2X15rGy2tN4+W1pvHyTrOmpXEujMllEdlsCpNZaq9lPSAsrawd+tgq5nzo8Yvp0ede1qNgea1pvLzWNF5eaxovrzWNl9eaxss7zZqWxrkwJpdFZLMpTMYzLPuXZ83i5bWm8fJa03h5rWm8vNY0Xl5rGi+vVxZROpdFZLMpTMbvbu8/1u/jx8trTePltabx8lrTeHmtaby81jReXu9ZROlcFpHNpjA5nwqx/1g9ipdXj+Ll1aN4efUoXl49ipdXj+Ll9WlolMxlEdlsCpPbHAxTc3l132cRFhbbqbm8mjYHw0MbW8WcdxurR/Hy6lG8vHoUL68excurR/Hy6lG8vNPMWRLnwphcFpHNppDveu9manW6aWllLbU63fTqm29v+/NeLy+d1dhzl66lc5deP9Q5JxmrR/Hy6lG8vHoUL68excurR/Hy6lG8vNPMWQLnwphcFpHNpgAAADDfnAtjcllENpsCAADAfHMujMllEdlsCvk2ev2tl5a2t15aemX9rW1/3uj1Zz723eM2ev27fq3UvIcxZ93yWtN4ea1pvLzWNF5ePYqXV4/i5Z2nHpXAuTAml0VksylMrqQ3zjv2gyrtjRRLfjPEUvJa03h5rWm8vNY0Xl49ipdXj+LlnacelcS5MCaXRWSzKUyuuVz+R3JOM7aKvLOYs255rWm8vNY0Xl5rGi+vHsXLq0fx8s5Tj0riXBiTyyKy2RQms9Hr7/uswbtrYbGdrvduZo99df3ticdNM7aKvNPOWbe81jReXmsaL681jZdXj+Ll1aN4eeepR6VxLozJZRHZbAqTaXW6Ez0Y3KlWp5s99vT5y1njphlbRd5p5qxbXmsaL681jZfXmsbLq0fx8upRvLzz1KPSOBfG5LKIbDaFySy117IeEJZW1rLHPvrcy1njphlbRd5p5qxbXmsaL681jZfXmsbLq0fx8upRvLzz1KPSOBfG5LKIbDaFydTpGYtpxnpGqMw565bXmsbLa03j5bWmelTnvHoUL+889ag0zoUxuSwim01hMnX5Xehpxvpd8zLnrFteaxovrzWNl9ea6lHd8+pRvLzz1KPSOBfG5LKIbDaFydXhUxamGVv1p0LMS15rGi+vNY2X15rGy6tH8fLqUby889SjkjgXxuSyiGw2hcltDoapuby677MIC4vt1FxeTZuD4dRjdxt37AeVM7aKvAc5Z93yWtN4ea1pvLzWNF5ePYqXV4/i5Z2nHpXEuTAml0Vksynku967mVqdblpaWUutTje9+ubb2/6818tLc8e+e9z13s27fq3UvIcxZ93yWtN4ea1pvLzWNF5ePYqXV4/i5Z2nHpXAuTAml0VksykAAADMN+fCmFwWkc2mkG+j1996tqC99WzBlfW3tv15o9ef+dh3j9vo9e/6tXnOq0fx8upRvLx6FC+vHsXLq0eHO2fd8lrT2Y4tgXNhTC6LyGZTmFxJvwtdt/fNOMi8ehQvrx7Fy6tH8fLqUby8elTNnHXLa01nM7YkzoUxuSwim01hcs3l8j9lYZqxdc2rR/Hy6lG8vHoUL68excurR2XNWbe81nTyPpXCuTAml0VksylMZqPX3/eZinfXwmI7Xe/dzB776vrbE4+bZmwd8+pRvLx6FC+vHsXLq0fx8upReXPWLa81naxPJXEujMllEdlsCpNpdboTPxg89PjF1Op0s8eePn85a9w0Y+uWV4/i5dWjeHn1KF5ePYqXV4/KnLNuea3p+H0qiXNhTC6LyGZTmMxSey3rwWBpZS177KPPvZz9IJQ7tm559SheXj2Kl1eP4uXVo3h59ajMOeuW15qO36eSOBfG5LKIbDaFyXhlUZl59SheXj2Kl1eP4uXVo3h59ajMOeuW15qO36eSOBfG5LKIbDaFyXjPojLz6lG8vHoUL68excurR/Hy6lF5c9YtrzWdrE8lcS6MyWUR2WwKk5uXT4WoW149ipdXj+Ll1aN4efUoXl49KmvOuuW1ppP3qRTOhTG5LCKbTWFym4Nhai6v7vsswsJiOzWXV9PmYDj12N3GHftB5YyNlleP4uXVo3h59SheXj2Kl1ePqpmzbnmt6WzGlsS5MCaXRWSzKeS73ruZWp1uWlpZS61ON7365tvb/rzXS0tzx7573PXezbt+bZ7z6lG8vHoUL68excurR/Hy6tHhzlm3vNZ0tmNL4FwYk8sistkUAAAA5ptzYUwui8hmU8i30etvPVPQ3nqmYKPXv+vXxhl7Zf2trHF1m1PeeHNGzatH8fLqUby8ehQvrx7Fy6tH440tgXNhTC6LyGZTmFyU36Mu9Xe35a3XnNHy6lG8vHoUL68excurR/Hy6pH3LKIMLovIZlOYXHM59ic0VDGnvPHmrGtePYqXV4/i5dWjeHn1KF5ePRpvbEmcC2NyWUQ2m8JkNnr9fZ+puFstLLbTq+tvTzw2d1zd5pQ33px1zHv8zMW0cEaPIuW1pvHyWtN4ea1pvLzWdLyxpb3ZtXNhTC6LyGZTmEyr0534weBOnT5/+VDH1W1OeePNWce8ehQvrx7Fy6tH8fLqUby8erR/tTrdqo822zgXxuSyiGw2hckstdeyHxAefe7lQx1XtznljTdnHfPqUby8ehQvrx7Fy6tH8fLq0f61tLJW9dFmG+fCmFwWkc2mMBmvLCpzrLxlzlnHvHoUL68excurR/Hy6lG8vHq0f3llEYfBZRHZbAqT8Z5F5Y2Vt8w565jXeyzEy2tN4+W1pvHyWtN4ea3peGO9ZxGHwWUR2WwKk4v+CQ1VfyqEvDHmrGtePYqXV4/i5dWjeHn1KF5ePRpvbEmcC2NyWUQ2m8LkNgfD1Fxe3fEswrEf1Du/trDYTs3l1bQ5GO459t017ri6zSlvvDmj5dWjeHn1KF5ePYqXV4/i5dWj8caWxLkwJpdFZLMp5Lveu5lanW5aWllLrU43Xe/dvOvXxhn76ptvZ42r25zyxpszal49ipdXj+Ll1aN4efUoXl49Gm9sCZwLY3JZRDabAgAAwHxzLozJZRHZbAr5Nnr9rWcK2lvPFGz0+nf92qzGVTV2XuaUN96c8sabU954c8obb055480p78HnLYFzYUwui8hmU5hclN/dLjGvHsXLq0fx8upRvLx6FC+vHsXLq0cx85bEuTAml0VksylMrrkc+1MhqsyrR/Hy6lG8vHoUL68excurR/Hy6lHMvCVxLozJZRHZbAqT2ej19/10hbvV8TMX08KZycctLLbTq+tvZ805zdgq8upRvLx6FC+vHsXLq0fx8upRvLx6FDNvaW927VwYk8sistkUJtPqdCd+MJi2Tp+/XMnYeZlT3nhzyhtvTnnjzSlvvDnljTenvAc7Z6vTrfpos41zYUwui8hmU5jMUnvt0B+EHn3u5UrGzsuc8sabU954c8obb055480pb7w55T3YOZdW1qo+2mzjXBiTyyKy2RQm45VF8eaUN96c8sabU954c8obb055480p78HO6ZVFHAaXRWSzKUzGexbFmlPeeHPKG29OeePNKW+8OeWNN6e8B5/XexZxGFwWkc2mMLm6fcpCnfLqUby8ehQvrx7Fy6tH8fLqUby8ehQzb0mcC2NyWUQ2m8LkNgfD1Fxe3fEswrEf1Du/trDYTs3l1bQ5GGaPm2bOuuXVo3h59SheXj2Kl1eP4uXVo3h59Shm3pI4F8bksohsNoV813s3U6vTTUsra6nV6abrvZt3/dqsxlU1dl7mlDfenPLGm1PeeHPKG29OeePNKe/B5y2Bc2FMLovIZlMAAACYb86FMbksIptNId9Gr7/1TEF765mCjV7/rl+b1bhZz7nX1+W1pvKWMWfdelS3vHoUL68excurR/Hy6lGZnAtjcllENpvC5Or0u9C7jTt+5mL63LOdHV+X15rKW86cdetR3fLqUby8ehQvrx7Fy6tH3rOIw+WyiGw2hck1l+vzKQs54+SNN6e88eaUN96c8sabU954c8obb84q85bGuTAml0VksylMZqPX3/GswTh1/MzFtHBm8nELi+306vrbhzqnvPHmlDfenPLGm1PeeHPKG29OeePNWVXehcV2cW927VwYk8sistkUJtPqdLMehKap0+cvH/qc8sabU954c8obb055480pb7w55Y03Z1V5W51u1UebbZwLY3JZRDabwmSW2muH/iD06HMvV/5AKG/955Q33pzyxptT3nhzyhtvTnnjzVlV3qWVtaqPNts4F8bksohsNoXJeGWRvHWdU954c8obb055480pb7w55Y03Z1V5vbKIw+CyiGw2hcl4zyJ56zinvPHmlDfenPLGm1PeeHPKG2/OqvJ6zyIOi8sistkUJudTIeSt25zyxptT3nhzyhtvTnnjzSlvvDmrzFsa58KYXBaRzaYwuc3BMDWXV3c8i3DsB/XOry0stlNzeTVtDobZ4w5izuNnLqbPPdvZ8XV5ram85cxZtx7VLa8excurR/Hy6lG8vHq0fWxJnAtjcllENptCvuu9m6nV6aallbXU6nTT9d7Nu35tVuNmPedeX5fXmspbxpx161Hd8upRvLx6FC+vHsXLq0dlci6MyWUR2WwKAAAA8825MCaXRWSzKQAAAMw358KYXBaRzaaQZ6PX33pJaXvrJaUbvf6eXz/IsaXOWbe81tSaRstrTePltabx8lrTeHmtaby8B72mpXAujMllEdlsCpM5iDfOO8g33avbG/1F6VHd8lrTeHmtaby81jReXmsaL681jZfXG1xTdy6LyGZTmExzeXXbhj9uNZer+TjPKubM7dO89Khuea1pvLzWNF5eaxovrzWNl9eaxss77ZqWxrkwJpdFZLMpjG+j19/xjMG4dfzMxbRw5nDHVjHnwmI7vbr+dlaf5qVHdctrTePltabx8lrTeHmtaby81jRe3mnWdGGxXdwnozkXxuSyiGw2hfG1Ot2sB6B5q9PnL1eeQVlT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AAAAxDgsAgAAAAAAQIzDIgAAAAAAAMQ4LAIAAAAAAECMwyIAAAAAAADEOCwCAAAAAABAjMMiAAAAAAAAxDgsAgAAAAAAQIzDIgAAAAAAAMQ4LAIAAAAAAECMwyIAAAAAAADEOCwCAAAAAABAjMMiAAAAAAAAxDgsAgAAAAAAQIzDIgAAAAAAAMQ4LAIAAAAAAECMwyIAAAAAAADEOCwCAAAAAABAjMMiAAAAAAAAxDgsAgAAAAAAQIzDIgAAAAAAAMQ4LAIAAAAAAECMwyIAAAAAAADEOCwCAAAAAABAjMMiAAAAAAAAxDgsAgAAAAAAQIzDIgAAAAAAAMQ4LAIAAAAAAECMwyIAAAAAAADEOCwCAAAAAABAjMMiAAAAAAAAxDgsAgAAAAAAQIzDIgAAAAAAAMQ4LAIAAAAAAECMwyIAAAAAAADEOCwCAAAAAABAjMMiAAAAAAAAxDgsAgAAAAAAQIzDIgAAAAAAAMQ4LAIAAAAAAECMwyIAAAAAAADEOCwCAAAAAABAjMMiAAAAAAAAxDgsAgAAAAAAQIzDIgAAAAAAAMQ4LAIAAAAAAEDs/wJ0ftOfkgFvrQAAAABJRU5ErkJggg==\" width=\"639.65\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x7f304c695d90>]"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"values = session['values']\n",
"plt.plot(values, '.')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Simple detection"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"peak_detector_simple = PeakDetectorSimple(threshold=5000)\n",
"peaks = detect_peaks(session['values'], peak_detector_simple)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure()\n",
"plt.plot(session['timestamps'], session['values'], '-', label='data')\n",
"plt.plot(session['timestamps'][peaks], session['values'][peaks], 'o', \n",
" label=f\"Simple {peak_detector_simple.threshold}\")\n",
"plt.title(\"Peak detection\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"for threshold in (500, 1000, 2000, 3000, 5000, 6000, 7000, 8000):\n",
" peak_detector_simple = PeakDetectorSimple(threshold=threshold)\n",
" peaks = detect_peaks(session['values'], peak_detector_simple)\n",
" print(f\"{threshold} : {len(peaks)}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Complex peak detection"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"lag = 20\n",
"peak_detector_zscore = PeakDetectorZScore(lag=lag, threshold=2, influence=0.1)\n",
"peaks = detect_peaks(session['values'], peak_detector_zscore)\n",
"up_down = np.array([0] * lag + peak_detector_zscore.up_down_signal)\n",
"up_down[up_down < 0] = -10\n",
"up_down[up_down > 0] = 10000\n",
"avgs = np.array([0] * lag + peak_detector_zscore._filter.means)\n",
"filtered = np.array([0] * lag + peak_detector_zscore._filter.filtered)\n",
"upper_bounds = np.array([0] * lag + peak_detector_zscore._filter.upper_bounds)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure()\n",
"plt.plot(session['timestamps'], session['values'], 'x-', label='data')\n",
"plt.plot(session['timestamps'], filtered, 'x', label='filtered')\n",
"#plt.plot(session['timestamps'], up_down, '-', label='up_down')\n",
"plt.plot(session['timestamps'], avgs, '-', label='avg')\n",
"#plt.plot(session['timestamps'], upper_bounds, '-', label='uppe bounds')\n",
"\n",
"plt.plot(session['timestamps'][peaks], session['values'][peaks], 'o', \n",
" label=f\"Peaks\")\n",
"plt.title(\"Peak detection\")\n",
"plt.legend()\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.7.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}