Skip to content

Instantly share code, notes, and snippets.

@rbaron
Created March 22, 2018 20:53
Show Gist options
  • Save rbaron/658361772457011be6eea0e061ae94c3 to your computer and use it in GitHub Desktop.
Save rbaron/658361772457011be6eea0e061ae94c3 to your computer and use it in GitHub Desktop.
Differential privacy simulation
{
"cells": [
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib notebook\n",
"import collections\n",
"\n",
"import numpy as np\n",
"import numpy.random as rnd\n",
"\n",
"import matplotlib.pyplot as plt\n",
"\n",
"rnd.seed(0)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"REAL_DISEASE_FREQ = 0.1\n",
"\n",
"N_SAMPLES = 100000"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"def simulate_single_answer():\n",
" # Honest answer: True if has disease, False otherwise\n",
" if rnd.random() < 0.5:\n",
" return rnd.random() < REAL_DISEASE_FREQ\n",
" # Fake answer. Random choice with probability .5\n",
" else:\n",
" return rnd.random() < 0.5"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"database = [simulate_single_answer() for i in range(N_SAMPLES)]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Frequentist estimation of _p_\n",
"\n",
"Probability of answering True:\n",
"P(HEADS) * p + P(TAILS) * 0.5 = #True/#Total\n",
"\n",
"=> p = 2*(#True/#Total - 0.25)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Estimated p: 0.09919999999999995\n"
]
}
],
"source": [
"def estimate_p(db):\n",
" counter = collections.Counter(db)\n",
" return 2*(counter[True]/len(db) - 0.25)\n",
"\n",
"print('Estimated p:', estimate_p(database))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Convergence plot"
]
},
{
"cell_type": "code",
"execution_count": 22,
"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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\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,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9koXXnhhvm/BggXb8QohTX/+85/jFa94RV53F1100YAfu2XLlvy2k/vvv3+/e/fff//Isiz22Wef2LJlS69jK1asyJ//Ax/4QM1zbDuEOOmkkwZ8nZCaoQjb1De0rlmzZuX1cuONN9bc95e//CV22GGHyLIsjj766Pzn6htaz7bfxzh58uR+927YsCHfe9xxx+U/V9vQGgYbtrVa7V5xxRX58WuvvbbmeebOnZvvu+KKK+q8SiBC2AYMkXvvvbfuX+r09PTEpEmTIsuyGDNmTDz99NPb+SohLRs3bozXvva1eW1+8pOfHPQ5zjjjjPzxXV1dfe7p6urK93zwgx/sc8/W2t99991j48aNfe7ZNoy//vrrB32twN/U+862CPUNrernP/95Xi/vete7au67+uqr833nnXder2PqG1pLT09Pfju2vffeu9+7wWx7y7kzzzyz1zG1Dc032LAtorVqd+3atbHjjjtGlmVxzDHH1LzmY445JrLsme+P7O8TcMDfCNuAIbP1VpJtbW2xePHiquNz5szJG/655567/S8QErJp06Y4+uij85qbOnVqQ+dZsWJFPOc5z4ksy6KzszOeeOKJXsefeOKJ6OzszGv/oYce6vM8297y4kMf+lDV8V/96lf5AOKlL31pvwMIoL6BhG3qG1rXP//zP+cDrttvv73q+Nq1a+OFL3xhZFkWO+20U/z2t7/tdVx9Q+s56aST8nr61Kc+NiTptgAABXBJREFU1eeeRx99tNft3yvvBqO2ofkaCdtarXa3vZXkDTfcUHX8+uuvH/RrBIRtwBBaunRp7LrrrpFlWYwcOTIuuOCC6OrqijvuuKPXfac7Ojpiw4YNzb5cKLXjjz8+r7mjjjoqfvGLX8QDDzxQc61YsaLmuc4+++z8XIccckhce+21cd9998W1114bhxxySH5sxowZNc/x17/+tden7CZPnhw//OEP4957740vfvGLseeee+ZDxfnz5xfxTwJJGUjYFqG+oVWtWLEixowZE1mWxS677BJnn3123H333XHffffFl7/85Txoy7IsZs+e3ec51De0luXLl0d7e3teT29+85vjxhtvjKVLl8bixYvjkksuifHjx+fH3/CGN/R5HrUN29eiRYviqquuytfFF1+c185rX/vaXseuuuqqmudppdp95JFH8u99bWtri0984hOxaNGiWLRoUXziE5+Itra2yLIsxo4dG2vWrHk2/3yQFGEbMKRuvvnm/K9o+lodHR2xcuXKZl8mlF6tGqy1XvziF9c8V09PT7z3ve/t9/Hve9/7oqenp99rWrduXRx66KE1z7HzzjvHlVdeOcT/EpCmgYZt6hta16JFi2KvvfaqWVc77LBDnHPOOTUfr76h9dx2222xxx571P3d/KijjopHH320z3Oobdi+Bvt9ybW0Wu0uWbIkxo0bV/M848aNiyVLlgz63wtSJmwDhtzq1atj2rRp0dHREe3t7TFmzJjo7OyM2bNn17ynNDC0hjJs2+qWW26Jt771rbH33nvHTjvtFHvvvXe89a1vHdRfu27evDm+8pWvxOGHHx7Pf/7zY5dddol99903TjvttHjwwQefxSsGtjXQsG0r9Q2taf369XHuuefGwQcfHKNGjYpddtklXvKSl8R73vOeWLp06YDOob6htaxfvz5mz54dr3/962Ps2LHx3Oc+N3bdddd4yUteEieeeGJ8//vfjy1bttQ9j9qG7WOowratWql2161bF+ecc0687GUvi5EjR8bIkSPj5S9/eZxzzjmxfv36AZ8HeIawDQAAAAAAABokbAMAAAAAAIAGCdsAAAAAAACgQcI2AAAAAAAAaJCwDQAAAAAAABokbAMAAAAAAIAGCdsAAAAAAACgQcI2AAAAAAAAaJCwDQAAAAAAABokbAMAAAAAAIAGCdsAAAAAAACgQcI2AAAAAAAAaJCwDQAAAAAAABokbAMAAAAAAIAGCdsAAAAAAACgQcI2AAAAAAAAaJCwDQAAAAAAABokbAMAAAAAAIAGCdsAAAAAAACgQcI2AAAAAAAAaJCwDQAAAAAAABokbAMAAAAAAIAGCdsAAAAAAACgQcI2AAAAAAAAaJCwDQAAAAAAABokbAMAAAAAAIAGCdsAAAAAAACgQcI2AAAAAAAAaJCwDQAAAAAAABokbAMAAAAAAIAGCdsAAAAAAACgQcI2AAAAAAAAaJCwDQAAAAAAABokbAMAAAAAAIAGCdsAAAAAAACgQcI2AAAAAAAAaJCwDQAAAAAAABokbAMAAAAAAIAGCdsAAAAAAACgQcI2AAAAAAAAaJCwDQAAAAAAABokbAMAAAAAAIAGCdsAAAAAAACgQcI2AAAAAAAAaJCwDQAAAAAAABokbAMAAAAAAIAGCdsAAAAAAACgQcI2AAAAAAAAaJCwDQAAAAAAABokbAMAAAAAAIAGCdsAAAAAAACgQcI2AAAAAAAAaJCwDQAAAAAAABokbAMAAAAAAIAGCdsAAAAAAACgQcI2AAAAAAAAaJCwDQAAAAAAABokbAMAAAAAAIAGCdsAAAAAAACgQcI2AAAAAAAAaJCwDQAAAAAAABokbAMAAAAAAIAG/T9/+tc4dODv3gAAAABJRU5ErkJggg==\" width=\"877.5\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x105e8c828>]"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"estimations = [estimate_p(database[:i]) for i in range(1, N_SAMPLES, 100)]\n",
"\n",
"plt.plot(estimations)"
]
}
],
"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.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment