{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this notebook, I evaluate the gradient expressions we use for Metropolis-Hastings. Specifically, I want to understand how good/bad the approximation we use for the reject case is. Let me present the gradient expressions we use first (see the manuscript for details)\n",
    "$$\n",
    "\\nabla_{\\theta} \\log P_{\\theta}(x'| x) = \\begin{cases}\n",
    "        \\nabla_{\\theta} \\log q_{\\theta}(x'|x) & \\text{accept} \\wedge a_{\\theta}(x \\to x') = 1 \\\\\n",
    "        \\nabla_{\\theta} \\log q_{\\theta}(x|x') & \\text{accept} \\wedge a_{\\theta}(x \\to x') < 1 \\\\\n",
    "        \\nabla_{\\theta} \\log [q_{\\theta}(x_p|x)(1 - a_{\\theta}(x \\to x_p))] & \\text{reject}\\,\\, (x'=x) \\\\\n",
    "    \\end{cases}\n",
    "$$\n",
    "Here, $x_p$ is the proposed (but ultimately rejected) state for sample $x$.\n",
    "\n",
    "I'll do the evaluation on a simple problem: sampling from a unit 1D Gaussian with a Gaussian proposal with a state-dependent mean."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import scipy.stats as st\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib notebook\n",
    "\n",
    "def p(x):\n",
    "    return st.norm.pdf(x)\n",
    "\n",
    "def q(x, xp, params):\n",
    "    \"\"\"\n",
    "    Proposal probability q(xp|x)\n",
    "    \"\"\"\n",
    "    w = params\n",
    "    m = x + w*x\n",
    "    return st.norm.pdf(xp, loc=m, scale=1.0)\n",
    "\n",
    "def grad_q(x, xp, params):\n",
    "    \"\"\"\n",
    "    Derivative of proposal probability q(xp|x)\n",
    "    \"\"\"\n",
    "    w = params\n",
    "    m = x + w*x\n",
    "    return q(x, xp, params) * (xp - m) * x\n",
    "\n",
    "def a(x, xp, params):\n",
    "    \"\"\"\n",
    "    Acceptance ratio a(x -> xp) (not rectified to be <= 1.0)\n",
    "    \"\"\"\n",
    "    a = (p(xp) * q(xp, x, params)) / (p(x) * q(x, xp, params))\n",
    "    return a\n",
    "\n",
    "def accept_prob(x, xp, params):\n",
    "    \"\"\"\n",
    "    Acceptance probability of x -> xp = min(1, a(x -> xp))\n",
    "    \"\"\"\n",
    "    ar = a(x, xp, params)\n",
    "    if ar > 1.0:\n",
    "        ar = 1.0\n",
    "    return ar\n",
    "    \n",
    "def grad_log_pt(x, xp, params):\n",
    "    \"\"\"\n",
    "    Derivative of log T(x -> xp) when xp \\neq x\n",
    "    \"\"\"\n",
    "    if a(x, xp, params) > 1.0:\n",
    "        return grad_q(x, xp, params) / q(x, xp, params)\n",
    "    else:\n",
    "        return grad_q(xp, x, params) / q(xp, x, params)\n",
    "    \n",
    "def grad_log_pt_diff(x, xp, params, eps=1e-6):\n",
    "    \"\"\"\n",
    "    Finite difference derivative of log T(x -> xp) when xp \\neq x\n",
    "    \"\"\"\n",
    "    pt = np.log(q(x, xp, params) * accept_prob(x, xp, params))\n",
    "    params += eps\n",
    "    pt_dp = np.log(q(x, xp, params) * accept_prob(x, xp, params))\n",
    "    return (pt_dp - pt) / eps"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, I will look at the accept case. The expressions here are exact, and our gradient expressions should give values close to the one estimated using finite differences. Below, we generate random pairs of $(x, x')$ and calculate the gradient of $\\log P_{\\theta}(x'|x)$ using our method and the finite difference method."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\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",
       "            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",
       "        this.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 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);\n",
       "        canvas.attr('height', height);\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'];\n",
       "    var y0 = fig.canvas.height - msg['y0'];\n",
       "    var x1 = msg['x1'];\n",
       "    var y1 = fig.canvas.height - msg['y1'];\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;\n",
       "    var y = canvas_pos.y;\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 overriden (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",
       "    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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.colorbar.Colorbar at 0x7f3366f95ed0>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "params = -0.5\n",
    "N = 1000\n",
    "g_diff = np.zeros(N)\n",
    "g_our = np.zeros(N)\n",
    "ars = np.zeros(N)\n",
    "x = np.random.randn(N)\n",
    "xp = np.random.randn(N)\n",
    "for i in range(N):\n",
    "    g_diff[i] = grad_log_pt_diff(x[i], xp[i], params)\n",
    "    g_our[i] = grad_log_pt(x[i], xp[i], params)\n",
    "    ars[i] = a(x[i], xp[i], params)\n",
    "plt.scatter(g_diff, g_our, c=ars)\n",
    "plt.colorbar()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As we see, estimates from both methods lie on the $x=y$ line, i.e., they are equal."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, let us look at the reject case."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The above expression for the gradient in the reject case is (obviously) wrong. I have been using that in my simulations so far, and it is maybe no surprise that our method did not really work on any problem other than the toy 1D Gaussian example. Here, let us derive less wrong approximations to the gradient in the reject case. We would like to estimate $\\nabla_{\\theta} \\log P_{\\theta}(x'|x)$ where $x'=x$ because the proposed move at $x$ is rejected. We know\n",
    "$$\n",
    "P_{\\theta}(x'|x) = \\int q_{\\theta}(y|x) (1 - a_{\\theta}(x\\to y)) dy\n",
    "$$\n",
    "\n",
    "**Method 1** Do a Monte Carlo approximation to $P(x'|x)$ and then take its derivative.\n",
    "$$\n",
    "P_{\\theta}(x'|x) \\approx \\sum_{y \\sim q} (1 - a_{\\theta}(x\\to y))\n",
    "$$\n",
    "and\n",
    "$$\n",
    "\\nabla_{\\theta} \\log P_{\\theta}(x'|x) \\approx \\nabla_{\\theta} \\log \\sum_{y \\sim q} (1 - a_{\\theta}(x\\to y))\n",
    "$$\n",
    "finally\n",
    "$$\n",
    "\\nabla_{\\theta} \\log P_{\\theta}(x'|x) \\approx \\frac{\\sum_{y \\sim q} \\nabla_{\\theta} (1 - a_{\\theta}(x\\to y))}{\\sum_{y \\sim q} (1 - a_{\\theta}(x\\to y)}\n",
    "$$\n",
    "If we use a single $y$ sample, we get (method 1)\n",
    "$$\n",
    "\\nabla_{\\theta} \\log P_{\\theta}(x'|x) \\approx \\frac{\\nabla_{\\theta} (1 - a_{\\theta}(x\\to y))}{(1 - a_{\\theta}(x\\to y)}\n",
    "$$\n",
    "We took a few questionable steps here. We took the derivative of a Monte Carlo approximation. However, I don't know whether the derivative of a Monte Carlo approximation to a function is equal to the derivative of that function. Are there cases where this is not true and what are the convergence properties of such an approximation? \n",
    "\n",
    "**Method 2** Now, first take the derivative and then replace values with their Monte Carlo approximations.\n",
    "$$\n",
    "\\nabla_{\\theta} \\log P_{\\theta}(x'|x) = \\frac{\\nabla_{\\theta} P_{\\theta}(x'|x)}{P_{\\theta}(x'|x)} \n",
    "$$\n",
    "Push the derivative inside the integral for $P(x'|x)$ and after some manipulation, we get the following Monte Carlo approximation\n",
    "$$\n",
    "\\nabla_{\\theta} P_{\\theta}(x'|x) \\approx \\sum_{y \\sim q} (1 - a_{\\theta}(x\\to y)) \\nabla_{\\theta} \\log q_{\\theta}(y|x) + \\nabla_{\\theta} (1 - a_{\\theta}(x\\to y))\n",
    "$$\n",
    "We can replace the denominator with its Monte Carlo approximation as well to get \n",
    "$$\n",
    "\\nabla_{\\theta} \\log P_{\\theta}(x'|x) \\approx \\frac{\\sum_{y \\sim q} (1 - a_{\\theta}(x\\to y)) \\nabla_{\\theta} \\log q_{\\theta}(y|x) + \\nabla_{\\theta} (1 - a_{\\theta}(x\\to y))}{\\sum_{y \\sim q} (1 - a_{\\theta}(x\\to y))}\n",
    "$$\n",
    "If we use a single $y$ sample, we get (method 2)\n",
    "$$\n",
    "\\nabla_{\\theta} \\log P_{\\theta}(x'|x) \\approx \\frac{(1 - a_{\\theta}(x\\to y)) \\nabla_{\\theta} \\log q_{\\theta}(y|x) + \\nabla_{\\theta} (1 - a_{\\theta}(x\\to y))}{(1 - a_{\\theta}(x\\to y))}\n",
    "$$\n",
    "\n",
    "**Method 3** Another idea is to lower bound $\\log P_{\\theta}(x'|x)$ using Jensen's inequality and take the derivative. However, this would be useless since $f(x) > g(x)$ for all $x$ does not imply $f'(x) > g'(x)$. In any case, I still calculate this approximation below and compare it to other two."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def grad_log_pt_reject(x, params, eps=1e-6, n=500):\n",
    "    w = params\n",
    "    m = x + w*x\n",
    "    e = st.norm.rvs(size=n)\n",
    "    ys = m + e\n",
    "    pt = np.log(np.mean([1 - accept_prob(x, y, params) for y in ys]))\n",
    "    \n",
    "    params += eps\n",
    "    w = params\n",
    "    m = x + w*x\n",
    "    ys = m + e\n",
    "    pt_dp = np.log(np.mean([1 - accept_prob(x, y, params) for y in ys]))\n",
    "    \n",
    "    # finite difference method\n",
    "    grad_diff = (pt_dp - pt) / eps\n",
    "    \n",
    "    # our method (1)\n",
    "    def fn1(y):\n",
    "        if a(x, y, params) < 1.0:\n",
    "            return ((-p(y)/p(x)) * ((grad_q(y, x, params) * q(x, y, params)) - (q(y, x, params) * grad_q(x, y, params))) / q(x, y, params)**2), (1.0 - a(x, y, params))\n",
    "        else:\n",
    "            return 0.0, 0.0\n",
    "    grad_our = np.array([fn1(y) for y in ys])\n",
    "    \n",
    "    def fn2(y):\n",
    "        if a(x, y, params) < 1.0:\n",
    "            return ((1.0 - a(x, y, params)) * grad_q(x, y, params) / q(x, y, params)) + ((-p(y)/p(x)) * ((grad_q(y, x, params) * q(x, y, params)) - (q(y, x, params) * grad_q(x, y, params))) / q(x, y, params)**2), (1.0 - a(x, y, params))\n",
    "        return 0.0, 0.0\n",
    "    grad_our2 = np.array([fn2(y) for y in ys])\n",
    "    \n",
    "    def fn3(y):\n",
    "        if a(x, y, params) < 1.0:\n",
    "            t1 = grad_q(x, y, params) * np.log(1.0 - a(x, y, params)) / q(x, y, params)\n",
    "            t2 = fn1(y)\n",
    "            t2 = t2[0] / t2[1]\n",
    "            return t1 + t2\n",
    "        else:\n",
    "            return 0.0\n",
    "    grad_our3 = np.array([fn3(y) for y in ys])\n",
    "            \n",
    "    return grad_diff, grad_our, grad_our2, grad_our3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "reps = 20\n",
    "\n",
    "xs = np.zeros(reps)\n",
    "ws = np.zeros(reps)\n",
    "rows = []\n",
    "for rep in range(reps):\n",
    "    params = 3 * (np.random.rand() - 0.5)\n",
    "    x = 2 * (np.random.rand() - 0.5)\n",
    "    xs[rep] = x\n",
    "    ws[rep] = params\n",
    "    \n",
    "    \n",
    "    g_diff, g_our, g_our2, g_our3 = grad_log_pt_reject(x, params, n=500)\n",
    "\n",
    "    # two ways to calculate estimate\n",
    "    # 1) ignore nans\n",
    "    s1 = g_our[:, 0] / g_our[:, 1]\n",
    "    e11 = np.nanmean(s1)\n",
    "    # 2) treat nans az 0\n",
    "    s1[np.isnan(s1)] = 0.0\n",
    "    e12 = np.mean(s1)\n",
    "    \n",
    "    e13 = np.mean(g_our[:,0]) / np.mean(g_our[:,1])\n",
    "\n",
    "    s2 = g_our2[:, 0] / g_our2[:, 1]\n",
    "    e21 = np.nanmean(s2)\n",
    "    s2[np.isnan(s2)] = 0.0\n",
    "    e22 = np.mean(s2)\n",
    "\n",
    "    e23 = np.mean(g_our2[:,0]) / np.mean(g_our2[:,1])\n",
    "    \n",
    "    s3 = g_our3\n",
    "    e31 = np.mean(s3[np.logical_not(np.isclose(s3, 0.0))])\n",
    "    e32 = np.mean(s3)\n",
    "    \n",
    "    rows.append({'our1_1': e11 - g_diff, 'our1_2': e12 - g_diff, 'our2_1': e21 - g_diff, \n",
    "                 'our2_2': e22 - g_diff, 'our3_1': e31 - g_diff, 'our3_2': e32 - g_diff,\n",
    "                'our1_3': e13 - g_diff, 'our2_3': e23 - g_diff})\n",
    "    \n",
    "df = pd.DataFrame(rows)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Are the single sample estimates close to the true value? And which method is better?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "our1_1    0.188972\n",
      "our1_2    1.064015\n",
      "our1_3    0.197713\n",
      "our2_1    0.130940\n",
      "our2_2    0.991488\n",
      "our2_3    0.023092\n",
      "our3_1    0.193339\n",
      "our3_2    1.065377\n",
      "dtype: float64\n"
     ]
    },
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\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",
       "            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",
       "        this.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 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);\n",
       "        canvas.attr('height', height);\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'];\n",
       "    var y0 = fig.canvas.height - msg['y0'];\n",
       "    var x1 = msg['x1'];\n",
       "    var y1 = fig.canvas.height - msg['y1'];\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;\n",
       "    var y = canvas_pos.y;\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 overriden (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",
       "    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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "array([[<matplotlib.axes._subplots.AxesSubplot object at 0x7f335a01e350>,\n",
       "        <matplotlib.axes._subplots.AxesSubplot object at 0x7f3359f91150>,\n",
       "        <matplotlib.axes._subplots.AxesSubplot object at 0x7f3359f15090>],\n",
       "       [<matplotlib.axes._subplots.AxesSubplot object at 0x7f3359e6ad50>,\n",
       "        <matplotlib.axes._subplots.AxesSubplot object at 0x7f3359df91d0>,\n",
       "        <matplotlib.axes._subplots.AxesSubplot object at 0x7f3359dc3950>],\n",
       "       [<matplotlib.axes._subplots.AxesSubplot object at 0x7f3359d50d90>,\n",
       "        <matplotlib.axes._subplots.AxesSubplot object at 0x7f3359cd4bd0>,\n",
       "        <matplotlib.axes._subplots.AxesSubplot object at 0x7f3359c41810>]], dtype=object)"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print df.abs().mean()\n",
    "df.hist(sharex=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It looks like method 2 gives the best results!"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}