Skip to content

Instantly share code, notes, and snippets.

@RedFlames
Created January 24, 2021 20:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RedFlames/6328d0e811ab318bb1b21eebf2a7a4cd to your computer and use it in GitHub Desktop.
Save RedFlames/6328d0e811ab318bb1b21eebf2a7a4cd to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"# imports ----------------------------------\n",
"import math\n",
"import random as rnd\n",
"import numpy as np\n",
"\n",
"from matplotlib.transforms import Bbox\n",
"import matplotlib.pyplot as plt\n",
"from mpl_toolkits.mplot3d import Axes3D"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"# constants / aliases -----------------------\n",
"vec = np.array\n",
"vlen = np.linalg.norm"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# normal generators -------------------------\n",
"\n",
"def normalize(v):\n",
" norm=np.linalg.norm(v, ord=2)\n",
" if norm==0:\n",
" norm=np.finfo(v.dtype).eps\n",
" return v/norm\n",
"\n",
"def random_normal(x_s=(-1.0, 1.0), y_s=(-1.0, 1.0), z_s=(-1.0, 1.0)):\n",
" return normalize(vec( (x_s[0]+(x_s[1]-x_s[0])*rnd.random(), \n",
" y_s[0]+(y_s[1]-y_s[0])*rnd.random(), \n",
" z_s[0]+(z_s[1]-z_s[0])*rnd.random()) ))\n",
"\n",
"def random_angled_normal():\n",
" u = rnd.random() * math.pi/2.0\n",
" v = rnd.random() * math.pi/2.0\n",
" return normalize(vec( (sin(u)*cos(v), sin(u)*sin(v), cos(u)) ))\n",
"\n",
"def random_angled_normal_2d():\n",
" u = rnd.random() * math.pi/2.0\n",
" return normalize(vec( (sin(u), cos(u), 0) ))\n",
"\n",
"def random_sqrt_normal():\n",
" ru = rnd.random()\n",
" su, cu = sqrt(ru), sqrt(1.0-ru)\n",
"\n",
" rv = rnd.random()\n",
" sv, cv = sqrt(rv), sqrt(1.0-rv)\n",
"\n",
" return normalize(vec( (su*cv, su*sv, cu) ))\n",
"\n",
"def random_sqrt_normal_2d():\n",
" ru = rnd.random()\n",
" su, cu = sqrt(ru), sqrt(1.0-ru)\n",
" return normalize(vec( (su, cu, 0) ))\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# plot helpers -----------------------\n",
"\n",
"def add_axes(ax, x=1, y=None, z=None, colval=1.0, lstyle=(0, (1, 5)), negatives=False):\n",
" if y is None:\n",
" y = x\n",
" if z is None:\n",
" z = x\n",
" ax.quiver((0,), (0,), (0,), (x,), (0,), (0,), colors=(colval, 0, 0, colval), linestyles=lstyle, arrow_length_ratio=0.1, zorder=99)\n",
" ax.quiver((0,), (0,), (0,), (0,), (y,), (0,), colors=(0, colval, 0, colval), linestyles=lstyle, arrow_length_ratio=0.1, zorder=99)\n",
" ax.quiver((0,), (0,), (0,), (0,), (0,), (z,), colors=(0, 0, colval, colval), linestyles=lstyle, arrow_length_ratio=0.1, zorder=99)\n",
" if negatives:\n",
" ax.quiver((0,), (0,), (0,), (-x,), (0,), (0,), colors=(colval, 0, 0, colval), linestyles=lstyle, arrow_length_ratio=0.1, zorder=99)\n",
" ax.quiver((0,), (0,), (0,), (0,), (-y,), (0,), colors=(0, colval, 0, colval), linestyles=lstyle, arrow_length_ratio=0.1, zorder=99)\n",
" ax.quiver((0,), (0,), (0,), (0,), (0,), (-z,), colors=(0, 0, colval, colval), linestyles=lstyle, arrow_length_ratio=0.1, zorder=99)\n",
" \n",
" ax.set_xlabel('x'); ax.set_xlim([-x, x]); ax.set_xticks([-1.0, 0.0, 1.0]);\n",
" ax.set_ylabel('y'); ax.set_ylim([y, -y]); ax.set_yticks([-1.0, 0.0, 1.0]);\n",
" ax.set_zlabel('z'); ax.set_zlim([-z, z]); ax.set_zticks([-1.0, 0.0, 1.0]);\n",
"\n",
"def quiver_vectors(ax, veclist, color=(0, 0.2, 0.8), arrow_length_ratio=0.3):\n",
" quiv = list()\n",
" for v in list(veclist):\n",
" quiv.append([0]*3 + list(v))\n",
" X, Y, Z, U, V, W = zip(*quiv)\n",
" ax.quiver(X, Y, Z, U, V, W, colors=color, arrow_length_ratio=arrow_length_ratio)\n",
"\n",
"def quiver_origin_vector(ax, vec, color=(0, 0.2, 0.8), arrow_length_ratio=0.3):\n",
" X, Y, Z, U, V, W = zip([0]*3 + list(vec))\n",
" ax.quiver(X, Y, Z, U, V, W, colors=color, arrow_length_ratio=arrow_length_ratio)\n"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Using matplotlib backend: nbAgg\n",
"Populating the interactive namespace from numpy and matplotlib\n",
"min/max(mv_x): 0.0018597318582742786 - 0.9988695372281022\n",
"min/max(mv_y): 0.0018597318582889882 - 0.9988695372281016\n"
]
}
],
"source": [
"# generate sample set ------------------------\n",
"\n",
"%matplotlib inline \n",
"%matplotlib notebook\n",
"%pylab\n",
"\n",
"plot_normals=False\n",
"\n",
"if plot_normals:\n",
" # prepare figure & plot\n",
" fig = plt.figure(figsize=(14, 14))\n",
" fig.set_tight_layout(True)\n",
" ax = fig.add_subplot(111, projection='3d')\n",
" add_axes(ax, 1.0, colval=.5, negatives=True)\n",
"\n",
"# arrays to collect samples per axis\n",
"mv_x, mv_y, mv_z = ([], [], [])\n",
"mv_xy = []\n",
"\n",
"for i in range(1,100000):\n",
" #r = random_angled_normal_2d()\n",
" r = random_sqrt_normal_2d()\n",
" mv_x.append(arccos(r[0])*2/math.pi)\n",
" mv_y.append(arcsin(r[1])*2/math.pi)\n",
" mv_z.append(r[2])\n",
" mv_xy.append([r[0], r[1]])\n",
" #print(np.linalg.norm(r))\n",
" if plot_normals and i <= 10000:\n",
" quiver_origin_vector(ax, r, (0.2, 0.2, 0.7), arrow_length_ratio=0.1)\n",
"\n",
"print(f\"min/max(mv_x): {numpy.amin(mv_x)} - {numpy.amax(mv_x)}\")\n",
"print(f\"min/max(mv_y): {numpy.amin(mv_y)} - {numpy.amax(mv_y)}\")\n",
"\n",
"# NOTE: sometimes the graphs would fail to render correctly\n",
"# (interacting with it and) running this cell again would fix it..."
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Using matplotlib backend: nbAgg\n",
"Populating the interactive namespace from numpy and matplotlib\n"
]
},
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"/* global mpl */\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(\n",
" '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",
"\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 = document.createElement('div');\n",
" this.root.setAttribute('style', 'display: inline-block');\n",
" this._root_extra_style(this.root);\n",
"\n",
" parent_element.appendChild(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 (fig.ratio !== 1) {\n",
" fig.send_message('set_dpi_ratio', { dpi_ratio: fig.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 = document.createElement('div');\n",
" titlebar.classList =\n",
" 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
" var titletext = document.createElement('div');\n",
" titletext.classList = 'ui-dialog-title';\n",
" titletext.setAttribute(\n",
" 'style',\n",
" 'width: 100%; text-align: center; padding: 3px;'\n",
" );\n",
" titlebar.appendChild(titletext);\n",
" this.root.appendChild(titlebar);\n",
" this.header = titletext;\n",
"};\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
"\n",
"mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
"\n",
"mpl.figure.prototype._init_canvas = function () {\n",
" var fig = this;\n",
"\n",
" var canvas_div = (this.canvas_div = document.createElement('div'));\n",
" canvas_div.setAttribute(\n",
" 'style',\n",
" 'border: 1px solid #ddd;' +\n",
" 'box-sizing: content-box;' +\n",
" 'clear: both;' +\n",
" 'min-height: 1px;' +\n",
" 'min-width: 1px;' +\n",
" 'outline: 0;' +\n",
" 'overflow: hidden;' +\n",
" 'position: relative;' +\n",
" 'resize: both;'\n",
" );\n",
"\n",
" function on_keyboard_event_closure(name) {\n",
" return function (event) {\n",
" return fig.key_event(event, name);\n",
" };\n",
" }\n",
"\n",
" canvas_div.addEventListener(\n",
" 'keydown',\n",
" on_keyboard_event_closure('key_press')\n",
" );\n",
" canvas_div.addEventListener(\n",
" 'keyup',\n",
" on_keyboard_event_closure('key_release')\n",
" );\n",
"\n",
" this._canvas_extra_style(canvas_div);\n",
" this.root.appendChild(canvas_div);\n",
"\n",
" var canvas = (this.canvas = document.createElement('canvas'));\n",
" canvas.classList.add('mpl-canvas');\n",
" canvas.setAttribute('style', 'box-sizing: content-box;');\n",
"\n",
" this.context = canvas.getContext('2d');\n",
"\n",
" var backingStore =\n",
" this.context.backingStorePixelRatio ||\n",
" this.context.webkitBackingStorePixelRatio ||\n",
" this.context.mozBackingStorePixelRatio ||\n",
" this.context.msBackingStorePixelRatio ||\n",
" this.context.oBackingStorePixelRatio ||\n",
" this.context.backingStorePixelRatio ||\n",
" 1;\n",
"\n",
" this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
" if (this.ratio !== 1) {\n",
" fig.send_message('set_dpi_ratio', { dpi_ratio: this.ratio });\n",
" }\n",
"\n",
" var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
" 'canvas'\n",
" ));\n",
" rubberband_canvas.setAttribute(\n",
" 'style',\n",
" 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
" );\n",
"\n",
" // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
" if (this.ResizeObserver === undefined) {\n",
" if (window.ResizeObserver !== undefined) {\n",
" this.ResizeObserver = window.ResizeObserver;\n",
" } else {\n",
" var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
" this.ResizeObserver = obs.ResizeObserver;\n",
" }\n",
" }\n",
"\n",
" this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
" var nentries = entries.length;\n",
" for (var i = 0; i < nentries; i++) {\n",
" var entry = entries[i];\n",
" var width, height;\n",
" if (entry.contentBoxSize) {\n",
" if (entry.contentBoxSize instanceof Array) {\n",
" // Chrome 84 implements new version of spec.\n",
" width = entry.contentBoxSize[0].inlineSize;\n",
" height = entry.contentBoxSize[0].blockSize;\n",
" } else {\n",
" // Firefox implements old version of spec.\n",
" width = entry.contentBoxSize.inlineSize;\n",
" height = entry.contentBoxSize.blockSize;\n",
" }\n",
" } else {\n",
" // Chrome <84 implements even older version of spec.\n",
" width = entry.contentRect.width;\n",
" height = entry.contentRect.height;\n",
" }\n",
"\n",
" // Keep the size of the canvas and rubber band canvas in sync with\n",
" // the canvas container.\n",
" if (entry.devicePixelContentBoxSize) {\n",
" // Chrome 84 implements new version of spec.\n",
" canvas.setAttribute(\n",
" 'width',\n",
" entry.devicePixelContentBoxSize[0].inlineSize\n",
" );\n",
" canvas.setAttribute(\n",
" 'height',\n",
" entry.devicePixelContentBoxSize[0].blockSize\n",
" );\n",
" } else {\n",
" canvas.setAttribute('width', width * fig.ratio);\n",
" canvas.setAttribute('height', height * fig.ratio);\n",
" }\n",
" canvas.setAttribute(\n",
" 'style',\n",
" 'width: ' + width + 'px; height: ' + height + 'px;'\n",
" );\n",
"\n",
" rubberband_canvas.setAttribute('width', width);\n",
" rubberband_canvas.setAttribute('height', height);\n",
"\n",
" // And update the size in Python. We ignore the initial 0/0 size\n",
" // that occurs as the element is placed into the DOM, which should\n",
" // otherwise not happen due to the minimum size styling.\n",
" if (width != 0 && height != 0) {\n",
" fig.request_resize(width, height);\n",
" }\n",
" }\n",
" });\n",
" this.resizeObserverInstance.observe(canvas_div);\n",
"\n",
" function on_mouse_event_closure(name) {\n",
" return function (event) {\n",
" return fig.mouse_event(event, name);\n",
" };\n",
" }\n",
"\n",
" rubberband_canvas.addEventListener(\n",
" 'mousedown',\n",
" on_mouse_event_closure('button_press')\n",
" );\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseup',\n",
" on_mouse_event_closure('button_release')\n",
" );\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband_canvas.addEventListener(\n",
" 'mousemove',\n",
" on_mouse_event_closure('motion_notify')\n",
" );\n",
"\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseenter',\n",
" on_mouse_event_closure('figure_enter')\n",
" );\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseleave',\n",
" on_mouse_event_closure('figure_leave')\n",
" );\n",
"\n",
" canvas_div.addEventListener('wheel', function (event) {\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" on_mouse_event_closure('scroll')(event);\n",
" });\n",
"\n",
" canvas_div.appendChild(canvas);\n",
" canvas_div.appendChild(rubberband_canvas);\n",
"\n",
" this.rubberband_context = rubberband_canvas.getContext('2d');\n",
" this.rubberband_context.strokeStyle = '#000000';\n",
"\n",
" this._resize_canvas = function (width, height, forward) {\n",
" if (forward) {\n",
" canvas_div.style.width = width + 'px';\n",
" canvas_div.style.height = height + 'px';\n",
" }\n",
" };\n",
"\n",
" // Disable right mouse context menu.\n",
" this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
" event.preventDefault();\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 toolbar = document.createElement('div');\n",
" toolbar.classList = 'mpl-toolbar';\n",
" this.root.appendChild(toolbar);\n",
"\n",
" function on_click_closure(name) {\n",
" return function (_event) {\n",
" return fig.toolbar_button_onclick(name);\n",
" };\n",
" }\n",
"\n",
" function on_mouseover_closure(tooltip) {\n",
" return function (event) {\n",
" if (!event.currentTarget.disabled) {\n",
" return fig.toolbar_button_onmouseover(tooltip);\n",
" }\n",
" };\n",
" }\n",
"\n",
" fig.buttons = {};\n",
" var buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'mpl-button-group';\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",
" /* Instead of a spacer, we start a new button group. */\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
" buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'mpl-button-group';\n",
" continue;\n",
" }\n",
"\n",
" var button = (fig.buttons[name] = document.createElement('button'));\n",
" button.classList = 'mpl-widget';\n",
" button.setAttribute('role', 'button');\n",
" button.setAttribute('aria-disabled', 'false');\n",
" button.addEventListener('click', on_click_closure(method_name));\n",
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
"\n",
" var icon_img = document.createElement('img');\n",
" icon_img.src = '_images/' + image + '.png';\n",
" icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
" icon_img.alt = tooltip;\n",
" button.appendChild(icon_img);\n",
"\n",
" buttonGroup.appendChild(button);\n",
" }\n",
"\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
"\n",
" var fmt_picker = document.createElement('select');\n",
" fmt_picker.classList = 'mpl-widget';\n",
" toolbar.appendChild(fmt_picker);\n",
" this.format_dropdown = fmt_picker;\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = document.createElement('option');\n",
" option.selected = fmt === mpl.default_extension;\n",
" option.innerHTML = fmt;\n",
" fmt_picker.appendChild(option);\n",
" }\n",
"\n",
" var status_bar = document.createElement('span');\n",
" status_bar.classList = 'mpl-message';\n",
" toolbar.appendChild(status_bar);\n",
" this.message = status_bar;\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",
"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",
"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], msg['forward']);\n",
" fig.send_message('refresh', {});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
" var x0 = msg['x0'] / fig.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
" var x1 = msg['x1'] / fig.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / fig.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,\n",
" 0,\n",
" fig.canvas.width / fig.ratio,\n",
" fig.canvas.height / fig.ratio\n",
" );\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",
" 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.handle_history_buttons = function (fig, msg) {\n",
" for (var key in msg) {\n",
" if (!(key in fig.buttons)) {\n",
" continue;\n",
" }\n",
" fig.buttons[key].disabled = !msg[key];\n",
" fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
" if (msg['mode'] === 'PAN') {\n",
" fig.buttons['Pan'].classList.add('active');\n",
" fig.buttons['Zoom'].classList.remove('active');\n",
" } else if (msg['mode'] === 'ZOOM') {\n",
" fig.buttons['Pan'].classList.remove('active');\n",
" fig.buttons['Zoom'].classList.add('active');\n",
" } else {\n",
" fig.buttons['Pan'].classList.remove('active');\n",
" fig.buttons['Zoom'].classList.remove('active');\n",
" }\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",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data\n",
" );\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" } else if (\n",
" typeof evt.data === 'string' &&\n",
" evt.data.slice(0, 21) === 'data:image/png;base64'\n",
" ) {\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(\n",
" \"No handler for the '\" + msg_type + \"' message type: \",\n",
" msg\n",
" );\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(\n",
" \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
" e,\n",
" e.stack,\n",
" msg\n",
" );\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",
" }\n",
" if (e.target) {\n",
" targ = e.target;\n",
" } else if (e.srcElement) {\n",
" targ = e.srcElement;\n",
" }\n",
" if (targ.nodeType === 3) {\n",
" // defeat Safari bug\n",
" targ = targ.parentNode;\n",
" }\n",
"\n",
" // pageX,Y are the mouse positions relative to the document\n",
" var boundingRect = targ.getBoundingClientRect();\n",
" var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
" var y = e.pageY - (boundingRect.top + document.body.scrollTop);\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",
" }\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",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * this.ratio;\n",
" var y = canvas_pos.y * this.ratio;\n",
"\n",
" this.send_message(name, {\n",
" x: x,\n",
" y: y,\n",
" button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event),\n",
" });\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",
" // Prevent repeat events\n",
" if (name === 'key_press') {\n",
" if (event.which === this._key) {\n",
" return;\n",
" } else {\n",
" this._key = event.which;\n",
" }\n",
" }\n",
" if (name === 'key_release') {\n",
" this._key = null;\n",
" }\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which !== 17) {\n",
" value += 'ctrl+';\n",
" }\n",
" if (event.altKey && event.which !== 18) {\n",
" value += 'alt+';\n",
" }\n",
" if (event.shiftKey && event.which !== 16) {\n",
" value += 'shift+';\n",
" }\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, 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",
"\n",
"///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
"// prettier-ignore\n",
"var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"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\";/* global mpl */\n",
"\n",
"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 = document.getElementById(id);\n",
" var ws_proxy = comm_websocket_adapter(comm);\n",
"\n",
" function ondownload(figure, _format) {\n",
" window.open(figure.canvas.toDataURL());\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy, ondownload, element);\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;\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",
" fig.cell_info[0].output_area.element.on(\n",
" 'cleared',\n",
" { fig: fig },\n",
" fig._remove_fig_handler\n",
" );\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function (fig, msg) {\n",
" var width = fig.canvas.width / fig.ratio;\n",
" fig.cell_info[0].output_area.element.off(\n",
" 'cleared',\n",
" fig._remove_fig_handler\n",
" );\n",
" fig.resizeObserverInstance.unobserve(fig.canvas_div);\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.innerHTML =\n",
" '<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 / this.ratio;\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] =\n",
" '<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 () {\n",
" fig.push_to_output();\n",
" }, 1000);\n",
"};\n",
"\n",
"mpl.figure.prototype._init_toolbar = function () {\n",
" var fig = this;\n",
"\n",
" var toolbar = document.createElement('div');\n",
" toolbar.classList = 'btn-toolbar';\n",
" this.root.appendChild(toolbar);\n",
"\n",
" function on_click_closure(name) {\n",
" return function (_event) {\n",
" return fig.toolbar_button_onclick(name);\n",
" };\n",
" }\n",
"\n",
" function on_mouseover_closure(tooltip) {\n",
" return function (event) {\n",
" if (!event.currentTarget.disabled) {\n",
" return fig.toolbar_button_onmouseover(tooltip);\n",
" }\n",
" };\n",
" }\n",
"\n",
" fig.buttons = {};\n",
" var buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'btn-group';\n",
" var button;\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",
" /* Instead of a spacer, we start a new button group. */\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
" buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'btn-group';\n",
" continue;\n",
" }\n",
"\n",
" button = fig.buttons[name] = document.createElement('button');\n",
" button.classList = 'btn btn-default';\n",
" button.href = '#';\n",
" button.title = name;\n",
" button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
" button.addEventListener('click', on_click_closure(method_name));\n",
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
" buttonGroup.appendChild(button);\n",
" }\n",
"\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = document.createElement('span');\n",
" status_bar.classList = 'mpl-message pull-right';\n",
" toolbar.appendChild(status_bar);\n",
" this.message = status_bar;\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = document.createElement('div');\n",
" buttongrp.classList = 'btn-group inline pull-right';\n",
" button = document.createElement('button');\n",
" button.classList = 'btn btn-mini btn-primary';\n",
" button.href = '#';\n",
" button.title = 'Stop Interaction';\n",
" button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
" button.addEventListener('click', function (_evt) {\n",
" fig.handle_close(fig, {});\n",
" });\n",
" button.addEventListener(\n",
" 'mouseover',\n",
" on_mouseover_closure('Stop Interaction')\n",
" );\n",
" buttongrp.appendChild(button);\n",
" var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
" titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
"};\n",
"\n",
"mpl.figure.prototype._remove_fig_handler = function (event) {\n",
" var fig = event.data.fig;\n",
" if (event.target !== this) {\n",
" // Ignore bubbled events from children.\n",
" return;\n",
" }\n",
" fig.close_ws(fig, {});\n",
"};\n",
"\n",
"mpl.figure.prototype._root_extra_style = function (el) {\n",
" el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
"};\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function (el) {\n",
" // this is important to make the div 'focusable\n",
" el.setAttribute('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",
" } else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\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",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which === 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
" fig.ondownload(fig, null);\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(\n",
" 'matplotlib',\n",
" mpl.mpl_figure_comm\n",
" );\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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\" width=\"1008\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x7f1325f8a2b0>]"
]
},
"execution_count": 75,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from scipy.stats import multivariate_normal as scipy_mv_normal\n",
"from scipy.stats import uniform as scipy_uniform\n",
"from scipy.stats import norm as scipy_norm\n",
"\n",
"use_dist = scipy_uniform\n",
"\n",
"mu_x, std_x = use_dist.fit(mv_x)\n",
"fit_x = use_dist()\n",
"var_x = fit_x.var()\n",
"mu_y, std_y = use_dist.fit(mv_y)\n",
"fit_y = use_dist()\n",
"var_y = fit_y.var()\n",
"mu_z, std_z = use_dist.fit(mv_z)\n",
"fit_z = use_dist()\n",
"var_z = fit_z.var()\n",
"\n",
"gridX, gridY = np.meshgrid(np.linspace(-1,1,100),np.linspace(-1,1,100))\n",
"pos = np.empty(gridX.shape + (2,))\n",
"pos[:,:,0] = gridX\n",
"pos[:,:,1] = gridY\n",
"\n",
"mvn = scipy_mv_normal([mu_x, mu_y], [[var_x, 0], [0, var_y]])\n",
"\n",
"%matplotlib inline \n",
"%matplotlib notebook\n",
"%pylab\n",
"\n",
"fig = plt.figure(figsize=(9, 14), dpi=112)\n",
"fig.set_tight_layout(True)\n",
"\n",
"x = np.linspace(use_dist.ppf(0.01),\n",
" use_dist.ppf(0.99), 100)\n",
"\n",
"ax = fig.add_subplot(311)\n",
"\n",
"ax.plot(x, fit_x.pdf(x))\n",
"ax.hist(mv_x, density=True, histtype='stepfilled', bins=25, alpha=0.2)\n",
"\n",
"\n",
"ax = fig.add_subplot(312)\n",
"\n",
"ax.plot(x, fit_y.pdf(x))\n",
"ax.hist(mv_y, density=True, histtype='stepfilled', bins=25, alpha=0.2)\n",
"\n",
"ax = fig.add_subplot(313, aspect='equal')\n",
"ax.plot(mv_x, mv_y, 'b.', markersize=.05) # *list(zip(*mv_xy))\n",
"\n",
"\n",
"#ax = fig.add_subplot(414, projection='3d')\n",
"#ax.plot_surface(gridX, gridY, mvn.pdf(pos), cmap='viridis',linewidth=0)\n",
"#print(mvn.pdf(pos))\n",
"#ax.plot_surface(gridX, gridY, np.array(mv_xy), cmap='viridis',linewidth=0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.1"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment