Skip to content

Instantly share code, notes, and snippets.

@bbengfort
Last active June 2, 2020 19:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bbengfort/3f481af7f21cd1e5e4e64d87ed2e50fa to your computer and use it in GitHub Desktop.
Save bbengfort/3f481af7f21cd1e5e4e64d87ed2e50fa to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Data Generation\n",
"\n",
"This notebook contains helper functions to generate random time series data and insert it into BTrDB for testing and development."
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib notebook\n",
"\n",
"import uuid\n",
"import btrdb\n",
"import numpy as np\n",
"import pandas as pd\n",
"\n",
"from datetime import datetime\n",
"from btrdb.utils.timez import ns_delta, to_nanoseconds, ns_to_datetime"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'build': '5.1.15', 'majorVersion': 5, 'proxy': {'proxyEndpoints': []}}"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"db = btrdb.connect()\n",
"db.info()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Random Walks\n",
"\n",
"To better simulate time series data, the generate function returns a random walk: \n",
"\n",
"https://machinelearningmastery.com/gentle-introduction-random-walk-times-series-forecasting-python/"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"def coin_flip():\n",
" return -1 if np.random.rand() < 0.5 else 1\n",
" \n",
"\n",
"def random_walk(n):\n",
" data = [coin_flip()]\n",
" for i in range(1, n):\n",
" data.append(\n",
" data[i-1] + coin_flip()\n",
" )\n",
" return np.array(data)\n",
" \n",
" \n",
"def generate(n, hz=30, loc=0, scale=1):\n",
" \"\"\"\n",
" Generate n timestamps, values\n",
" \"\"\"\n",
" start = to_nanoseconds(datetime.now())\n",
" tstep = ns_delta(seconds=1/hz)\n",
" index = [\n",
" ns_to_datetime(start + (tstep*idx)) for idx in range(n)\n",
" ]\n",
" \n",
" values = (random_walk(n) * scale) + loc\n",
" return pd.Series(values, index=index)"
]
},
{
"cell_type": "code",
"execution_count": 30,
"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,iVBORw0KGgoAAAANSUhEUgAAAsAAAAIQCAYAAACPEdjAAAAgAElEQVR4XuydBXRVx/bGvySE4B4kuAR3aHB3alihxR5Wyp+WCqUUdwIFWtoHpRRrH9AWCkUqQUuQ4O5BEry4JMFj/zUnvTfn+rl6rnyzVtd7nLtnz8xv9km+O5nZ45eampoKFhIgARIgARIgARIgARLwEQJ+FMA+MtMcJgmQAAmQAAmQAAmQgESAApiBQAIkQAIkQAIkQAIk4FMEKIB9aro5WBIgARIgARIgARIgAQpgxgAJkAAJkAAJkAAJkIBPEaAA9qnp5mBJgARIgARIgARIgAQogBkDJEACJEACJEACJEACPkWAAtinppuDJQESIAESIAESIAESoABmDJAACZAACZAACZAACfgUAQpgn5puDpYESIAESIAESIAESIACmDFAAiRAAiRAAiRAAiTgUwQogH1qujlYEiABEiABEiABEiABCmDGAAmQAAmQAAmQAAmQgE8RoAD2qenmYEmABEiABEiABEiABCiAGQMkQAIkQAIkQAIkQAI+RYAC2Kemm4MlARIgARIgARIgARKgAGYMkAAJkAAJkAAJkAAJ+BQBCmCfmm4OlgRIgARIgARIgARIgAKYMUACJEACJEACJEACJOBTBCiAfWq6OVgSIAESIAESIAESIAEKYMYACZAACZAACZAACZCATxGgAPap6eZgSYAESIAESIAESIAEKIAZAyRAAiRAAiRAAiRAAj5FgALYp6abgyUBEiABEiABEiABEqAAZgyQAAmQAAmQAAmQAAn4FAEKYJ+abg6WBEiABEiABEiABEiAApgxQAIkQAIkQAIkQAIk4FMEKIB9aro5WBIgARIgARIgARIgAQpgxgAJkAAJkAAJkAAJkIBPEaAA9qnp5mBJgARIgARIgARIgAQogBkDJEACJEACJEACJEACPkWAAtinppuDJQESIAESIAESIAESoABmDJAACZAACZAACZAACfgUAQpgn5puDpYESIAESIAESIAESIACmDFAAiRAAiRAAiRAAiTgUwQogH1qujlYEiABEiABEiABEiABCmDGAAmQAAmQAAmQAAmQgE8RoAD2qenmYEmABEiABEiABEiABCiAGQMkQAIkQAIkQAIkQAI+RYAC2Kemm4MlARIgARIgARIgARKgAGYMkAAJkAAJkAAJkAAJ+BQBCmCfmm4OlgRIgARIgARIgARIgAKYMUACJEACJEACJEACJOBTBCiAfWq6OVgSIAESIAESIAESIAEKYMYACZAACZAACZAACZCATxGgAPap6eZgSYAESIAESIAESIAEKIAZAyRAAiRAAiRAAiRAAj5FgALYp6abgyUBEiABEiABEiABEqAAZgyQAAmQAAmQAAmQAAn4FAEKYJ+abg6WBEiABEiABEiABEiAApgxQAIkQAIkQAIkQAIk4FMEKIB9aro5WBIgARIgARIgARIgAQpgxgAJkAAJkAAJkAAJkIBPEaAA9qnp5mBJgARIgARIgARIgAQogBkDJEACJEACJEACJEACPkWAAtinppuDJQESIAESIAESIAESoABmDJAACZAACZAACZAACfgUAQpgn5puDpYESIAESIAESIAESIACmDFAAiRAAiRAAiRAAiTgUwQogH1qujlYEiABEiABEiABEiABCmDGAAmQAAmQAAmQAAmQgE8RoAD2qenmYEmABEiABEiABEiABCiAnRgDz58/x8mTJxEcHIwMGTI4sSW6JgESIAESIAESIAFdAklJSbh79y6qVKmCTJkyEY+MAAWwE8Ph4MGDCAsLc2ILdE0CJEACJEACJEAC5gkcOHAAr7zyCjFRALsmBi5fvoySJUtCBF6hQoVc0yhbIQESIAESIAESIAEAN2/elBbiLl26hBIlSpCJJwngiIgIfPHFFzhz5gzi4+NRuHBhdOjQAePHj0fOnDmRnJyML7/8En/++adkk5KSgmrVqmHSpElo1KiRzmS/fPkSo0ePxrJly5CQkID69etj7ty5KFeunI5ddHQ0hgwZgj179iB79uzo3bs3pkyZgowZM1oVPNevX0fRokVx7do1FClSxKq6NCYBEiABEiABEiABewhQh5im5/ZbIJYvX44TJ06gTp06yJs3L06dOoUJEyagZs2a2Lx5Mx4/fiyJzD59+qBly5YICAjAggUL8Pvvv0ufN2/eXDv6QYMGYcWKFfjqq68kIT116lTExsbi9OnTkpgW5eHDh6hUqRJCQ0MxatQo3LhxA0OHDkXPnj0lsWxNYeBZQ4u2JEACJEACJEACjiRAHeLBAthY1xcuXIiBAwdK4rRAgQLSynDu3Lm1pmJVuHLlyihTpgz++OMP6bkIArH8P2/ePKmuKA8ePECxYsUwbtw4DB8+XHo2bdo0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\" width=\"639.9999861283738\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x10c410f98>"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data = generate(40000, loc=3000, scale=1.2)\n",
"data.plot()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Insert into BTrDB"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"UUID('f2bf4207-a49e-4b3d-8fdb-04535b524531')"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"uuid.uuid4()"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<btrdb.stream.Stream at 0x10d61a978>"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def new_stream(data, collection=\"datagen\", name=None, annotations=None):\n",
" uu = uuid.uuid4()\n",
" tags = {\n",
" \"name\": name or datetime.now().strftime(\"random-walk-%Y%m%d\")\n",
" }\n",
" \n",
" stream = db.create(uu, collection, tags=tags, annotations=annotations)\n",
" \n",
" data = [\n",
" (to_nanoseconds(data.index[i]), data[i])\n",
" for i in range(len(data))\n",
" ]\n",
" \n",
" stream.insert(data)\n",
" return stream\n",
" \n",
" \n",
"new_stream(data)"
]
}
],
"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.6.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment