1{
2 "cells": [
3  {
4   "cell_type": "code",
5   "execution_count": 1,
6   "metadata": {},
7   "outputs": [],
8   "source": [
9    "# core stuff\n",
10    "import numpy as np\n",
11    "import pickle as pk\n",
12    "from copy import deepcopy\n",
13    "\n",
14    "# plotting stuff\n",
15    "import matplotlib.pyplot as plt\n",
16    "from mpl_toolkits import mplot3d\n",
17    "from matplotlib import rc\n",
18    "rc('font',**{'family':'sans-serif','sans-serif':['Helvetica']})\n",
19    "## for Palatino and other serif fonts use:\n",
20    "#rc('font',**{'family':'serif','serif':['Palatino']})\n",
21    "rc('text', usetex=True)\n",
22    "%matplotlib notebook\n",
23    "\n",
24    "# Ensure that changes in imported module (gravann most importantly) are autoreloaded\n",
25    "%load_ext autoreload\n",
26    "%autoreload 2\n"
27   ]
28  },
29  {
30   "cell_type": "code",
31   "execution_count": 2,
32   "metadata": {},
33   "outputs": [],
34   "source": [
35    "# Load all data (produced using apophis.cpp benchmark)\n",
36    "with open(\"data/apophis_err.pk\", \"rb\") as file:\n",
37    "   err_apophis = pk.load(file)\n",
38    "err_apophis[:,0] = err_apophis[:,0] / 60 / 60 / 24 / 365.25"
39   ]
40  },
41  {
42   "cell_type": "code",
43   "execution_count": 27,
44   "metadata": {},
45   "outputs": [
46    {
47     "data": {
48      "application/javascript": [
49       "/* Put everything inside the global mpl namespace */\n",
50       "/* global mpl */\n",
51       "window.mpl = {};\n",
52       "\n",
53       "mpl.get_websocket_type = function () {\n",
54       "    if (typeof WebSocket !== 'undefined') {\n",
55       "        return WebSocket;\n",
56       "    } else if (typeof MozWebSocket !== 'undefined') {\n",
57       "        return MozWebSocket;\n",
58       "    } else {\n",
59       "        alert(\n",
60       "            'Your browser does not have WebSocket support. ' +\n",
61       "                'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
62       "                'Firefox 4 and 5 are also supported but you ' +\n",
63       "                'have to enable WebSockets in about:config.'\n",
64       "        );\n",
65       "    }\n",
66       "};\n",
67       "\n",
68       "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
69       "    this.id = figure_id;\n",
70       "\n",
71       "    this.ws = websocket;\n",
72       "\n",
73       "    this.supports_binary = this.ws.binaryType !== undefined;\n",
74       "\n",
75       "    if (!this.supports_binary) {\n",
76       "        var warnings = document.getElementById('mpl-warnings');\n",
77       "        if (warnings) {\n",
78       "            warnings.style.display = 'block';\n",
79       "            warnings.textContent =\n",
80       "                'This browser does not support binary websocket messages. ' +\n",
81       "                'Performance may be slow.';\n",
82       "        }\n",
83       "    }\n",
84       "\n",
85       "    this.imageObj = new Image();\n",
86       "\n",
87       "    this.context = undefined;\n",
88       "    this.message = undefined;\n",
89       "    this.canvas = undefined;\n",
90       "    this.rubberband_canvas = undefined;\n",
91       "    this.rubberband_context = undefined;\n",
92       "    this.format_dropdown = undefined;\n",
93       "\n",
94       "    this.image_mode = 'full';\n",
95       "\n",
96       "    this.root = document.createElement('div');\n",
97       "    this.root.setAttribute('style', 'display: inline-block');\n",
98       "    this._root_extra_style(this.root);\n",
99       "\n",
100       "    parent_element.appendChild(this.root);\n",
101       "\n",
102       "    this._init_header(this);\n",
103       "    this._init_canvas(this);\n",
104       "    this._init_toolbar(this);\n",
105       "\n",
106       "    var fig = this;\n",
107       "\n",
108       "    this.waiting = false;\n",
109       "\n",
110       "    this.ws.onopen = function () {\n",
111       "        fig.send_message('supports_binary', { value: fig.supports_binary });\n",
112       "        fig.send_message('send_image_mode', {});\n",
113       "        if (fig.ratio !== 1) {\n",
114       "            fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n",
115       "        }\n",
116       "        fig.send_message('refresh', {});\n",
117       "    };\n",
118       "\n",
119       "    this.imageObj.onload = function () {\n",
120       "        if (fig.image_mode === 'full') {\n",
121       "            // Full images could contain transparency (where diff images\n",
122       "            // almost always do), so we need to clear the canvas so that\n",
123       "            // there is no ghosting.\n",
124       "            fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
125       "        }\n",
126       "        fig.context.drawImage(fig.imageObj, 0, 0);\n",
127       "    };\n",
128       "\n",
129       "    this.imageObj.onunload = function () {\n",
130       "        fig.ws.close();\n",
131       "    };\n",
132       "\n",
133       "    this.ws.onmessage = this._make_on_message_function(this);\n",
134       "\n",
135       "    this.ondownload = ondownload;\n",
136       "};\n",
137       "\n",
138       "mpl.figure.prototype._init_header = function () {\n",
139       "    var titlebar = document.createElement('div');\n",
140       "    titlebar.classList =\n",
141       "        'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
142       "    var titletext = document.createElement('div');\n",
143       "    titletext.classList = 'ui-dialog-title';\n",
144       "    titletext.setAttribute(\n",
145       "        'style',\n",
146       "        'width: 100%; text-align: center; padding: 3px;'\n",
147       "    );\n",
148       "    titlebar.appendChild(titletext);\n",
149       "    this.root.appendChild(titlebar);\n",
150       "    this.header = titletext;\n",
151       "};\n",
152       "\n",
153       "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
154       "\n",
155       "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
156       "\n",
157       "mpl.figure.prototype._init_canvas = function () {\n",
158       "    var fig = this;\n",
159       "\n",
160       "    var canvas_div = (this.canvas_div = document.createElement('div'));\n",
161       "    canvas_div.setAttribute(\n",
162       "        'style',\n",
163       "        'border: 1px solid #ddd;' +\n",
164       "            'box-sizing: content-box;' +\n",
165       "            'clear: both;' +\n",
166       "            'min-height: 1px;' +\n",
167       "            'min-width: 1px;' +\n",
168       "            'outline: 0;' +\n",
169       "            'overflow: hidden;' +\n",
170       "            'position: relative;' +\n",
171       "            'resize: both;'\n",
172       "    );\n",
173       "\n",
174       "    function on_keyboard_event_closure(name) {\n",
175       "        return function (event) {\n",
176       "            return fig.key_event(event, name);\n",
177       "        };\n",
178       "    }\n",
179       "\n",
180       "    canvas_div.addEventListener(\n",
181       "        'keydown',\n",
182       "        on_keyboard_event_closure('key_press')\n",
183       "    );\n",
184       "    canvas_div.addEventListener(\n",
185       "        'keyup',\n",
186       "        on_keyboard_event_closure('key_release')\n",
187       "    );\n",
188       "\n",
189       "    this._canvas_extra_style(canvas_div);\n",
190       "    this.root.appendChild(canvas_div);\n",
191       "\n",
192       "    var canvas = (this.canvas = document.createElement('canvas'));\n",
193       "    canvas.classList.add('mpl-canvas');\n",
194       "    canvas.setAttribute('style', 'box-sizing: content-box;');\n",
195       "\n",
196       "    this.context = canvas.getContext('2d');\n",
197       "\n",
198       "    var backingStore =\n",
199       "        this.context.backingStorePixelRatio ||\n",
200       "        this.context.webkitBackingStorePixelRatio ||\n",
201       "        this.context.mozBackingStorePixelRatio ||\n",
202       "        this.context.msBackingStorePixelRatio ||\n",
203       "        this.context.oBackingStorePixelRatio ||\n",
204       "        this.context.backingStorePixelRatio ||\n",
205       "        1;\n",
206       "\n",
207       "    this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
208       "\n",
209       "    var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
210       "        'canvas'\n",
211       "    ));\n",
212       "    rubberband_canvas.setAttribute(\n",
213       "        'style',\n",
214       "        'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
215       "    );\n",
216       "\n",
217       "    // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
218       "    if (this.ResizeObserver === undefined) {\n",
219       "        if (window.ResizeObserver !== undefined) {\n",
220       "            this.ResizeObserver = window.ResizeObserver;\n",
221       "        } else {\n",
222       "            var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
223       "            this.ResizeObserver = obs.ResizeObserver;\n",
224       "        }\n",
225       "    }\n",
226       "\n",
227       "    this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
228       "        var nentries = entries.length;\n",
229       "        for (var i = 0; i < nentries; i++) {\n",
230       "            var entry = entries[i];\n",
231       "            var width, height;\n",
232       "            if (entry.contentBoxSize) {\n",
233       "                if (entry.contentBoxSize instanceof Array) {\n",
234       "                    // Chrome 84 implements new version of spec.\n",
235       "                    width = entry.contentBoxSize[0].inlineSize;\n",
236       "                    height = entry.contentBoxSize[0].blockSize;\n",
237       "                } else {\n",
238       "                    // Firefox implements old version of spec.\n",
239       "                    width = entry.contentBoxSize.inlineSize;\n",
240       "                    height = entry.contentBoxSize.blockSize;\n",
241       "                }\n",
242       "            } else {\n",
243       "                // Chrome <84 implements even older version of spec.\n",
244       "                width = entry.contentRect.width;\n",
245       "                height = entry.contentRect.height;\n",
246       "            }\n",
247       "\n",
248       "            // Keep the size of the canvas and rubber band canvas in sync with\n",
249       "            // the canvas container.\n",
250       "            if (entry.devicePixelContentBoxSize) {\n",
251       "                // Chrome 84 implements new version of spec.\n",
252       "                canvas.setAttribute(\n",
253       "                    'width',\n",
254       "                    entry.devicePixelContentBoxSize[0].inlineSize\n",
255       "                );\n",
256       "                canvas.setAttribute(\n",
257       "                    'height',\n",
258       "                    entry.devicePixelContentBoxSize[0].blockSize\n",
259       "                );\n",
260       "            } else {\n",
261       "                canvas.setAttribute('width', width * fig.ratio);\n",
262       "                canvas.setAttribute('height', height * fig.ratio);\n",
263       "            }\n",
264       "            canvas.setAttribute(\n",
265       "                'style',\n",
266       "                'width: ' + width + 'px; height: ' + height + 'px;'\n",
267       "            );\n",
268       "\n",
269       "            rubberband_canvas.setAttribute('width', width);\n",
270       "            rubberband_canvas.setAttribute('height', height);\n",
271       "\n",
272       "            // And update the size in Python. We ignore the initial 0/0 size\n",
273       "            // that occurs as the element is placed into the DOM, which should\n",
274       "            // otherwise not happen due to the minimum size styling.\n",
275       "            if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
276       "                fig.request_resize(width, height);\n",
277       "            }\n",
278       "        }\n",
279       "    });\n",
280       "    this.resizeObserverInstance.observe(canvas_div);\n",
281       "\n",
282       "    function on_mouse_event_closure(name) {\n",
283       "        return function (event) {\n",
284       "            return fig.mouse_event(event, name);\n",
285       "        };\n",
286       "    }\n",
287       "\n",
288       "    rubberband_canvas.addEventListener(\n",
289       "        'mousedown',\n",
290       "        on_mouse_event_closure('button_press')\n",
291       "    );\n",
292       "    rubberband_canvas.addEventListener(\n",
293       "        'mouseup',\n",
294       "        on_mouse_event_closure('button_release')\n",
295       "    );\n",
296       "    // Throttle sequential mouse events to 1 every 20ms.\n",
297       "    rubberband_canvas.addEventListener(\n",
298       "        'mousemove',\n",
299       "        on_mouse_event_closure('motion_notify')\n",
300       "    );\n",
301       "\n",
302       "    rubberband_canvas.addEventListener(\n",
303       "        'mouseenter',\n",
304       "        on_mouse_event_closure('figure_enter')\n",
305       "    );\n",
306       "    rubberband_canvas.addEventListener(\n",
307       "        'mouseleave',\n",
308       "        on_mouse_event_closure('figure_leave')\n",
309       "    );\n",
310       "\n",
311       "    canvas_div.addEventListener('wheel', function (event) {\n",
312       "        if (event.deltaY < 0) {\n",
313       "            event.step = 1;\n",
314       "        } else {\n",
315       "            event.step = -1;\n",
316       "        }\n",
317       "        on_mouse_event_closure('scroll')(event);\n",
318       "    });\n",
319       "\n",
320       "    canvas_div.appendChild(canvas);\n",
321       "    canvas_div.appendChild(rubberband_canvas);\n",
322       "\n",
323       "    this.rubberband_context = rubberband_canvas.getContext('2d');\n",
324       "    this.rubberband_context.strokeStyle = '#000000';\n",
325       "\n",
326       "    this._resize_canvas = function (width, height, forward) {\n",
327       "        if (forward) {\n",
328       "            canvas_div.style.width = width + 'px';\n",
329       "            canvas_div.style.height = height + 'px';\n",
330       "        }\n",
331       "    };\n",
332       "\n",
333       "    // Disable right mouse context menu.\n",
334       "    this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
335       "        event.preventDefault();\n",
336       "        return false;\n",
337       "    });\n",
338       "\n",
339       "    function set_focus() {\n",
340       "        canvas.focus();\n",
341       "        canvas_div.focus();\n",
342       "    }\n",
343       "\n",
344       "    window.setTimeout(set_focus, 100);\n",
345       "};\n",
346       "\n",
347       "mpl.figure.prototype._init_toolbar = function () {\n",
348       "    var fig = this;\n",
349       "\n",
350       "    var toolbar = document.createElement('div');\n",
351       "    toolbar.classList = 'mpl-toolbar';\n",
352       "    this.root.appendChild(toolbar);\n",
353       "\n",
354       "    function on_click_closure(name) {\n",
355       "        return function (_event) {\n",
356       "            return fig.toolbar_button_onclick(name);\n",
357       "        };\n",
358       "    }\n",
359       "\n",
360       "    function on_mouseover_closure(tooltip) {\n",
361       "        return function (event) {\n",
362       "            if (!event.currentTarget.disabled) {\n",
363       "                return fig.toolbar_button_onmouseover(tooltip);\n",
364       "            }\n",
365       "        };\n",
366       "    }\n",
367       "\n",
368       "    fig.buttons = {};\n",
369       "    var buttonGroup = document.createElement('div');\n",
370       "    buttonGroup.classList = 'mpl-button-group';\n",
371       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
372       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
373       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
374       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
375       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
376       "\n",
377       "        if (!name) {\n",
378       "            /* Instead of a spacer, we start a new button group. */\n",
379       "            if (buttonGroup.hasChildNodes()) {\n",
380       "                toolbar.appendChild(buttonGroup);\n",
381       "            }\n",
382       "            buttonGroup = document.createElement('div');\n",
383       "            buttonGroup.classList = 'mpl-button-group';\n",
384       "            continue;\n",
385       "        }\n",
386       "\n",
387       "        var button = (fig.buttons[name] = document.createElement('button'));\n",
388       "        button.classList = 'mpl-widget';\n",
389       "        button.setAttribute('role', 'button');\n",
390       "        button.setAttribute('aria-disabled', 'false');\n",
391       "        button.addEventListener('click', on_click_closure(method_name));\n",
392       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
393       "\n",
394       "        var icon_img = document.createElement('img');\n",
395       "        icon_img.src = '_images/' + image + '.png';\n",
396       "        icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
397       "        icon_img.alt = tooltip;\n",
398       "        button.appendChild(icon_img);\n",
399       "\n",
400       "        buttonGroup.appendChild(button);\n",
401       "    }\n",
402       "\n",
403       "    if (buttonGroup.hasChildNodes()) {\n",
404       "        toolbar.appendChild(buttonGroup);\n",
405       "    }\n",
406       "\n",
407       "    var fmt_picker = document.createElement('select');\n",
408       "    fmt_picker.classList = 'mpl-widget';\n",
409       "    toolbar.appendChild(fmt_picker);\n",
410       "    this.format_dropdown = fmt_picker;\n",
411       "\n",
412       "    for (var ind in mpl.extensions) {\n",
413       "        var fmt = mpl.extensions[ind];\n",
414       "        var option = document.createElement('option');\n",
415       "        option.selected = fmt === mpl.default_extension;\n",
416       "        option.innerHTML = fmt;\n",
417       "        fmt_picker.appendChild(option);\n",
418       "    }\n",
419       "\n",
420       "    var status_bar = document.createElement('span');\n",
421       "    status_bar.classList = 'mpl-message';\n",
422       "    toolbar.appendChild(status_bar);\n",
423       "    this.message = status_bar;\n",
424       "};\n",
425       "\n",
426       "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
427       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
428       "    // which will in turn request a refresh of the image.\n",
429       "    this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
430       "};\n",
431       "\n",
432       "mpl.figure.prototype.send_message = function (type, properties) {\n",
433       "    properties['type'] = type;\n",
434       "    properties['figure_id'] = this.id;\n",
435       "    this.ws.send(JSON.stringify(properties));\n",
436       "};\n",
437       "\n",
438       "mpl.figure.prototype.send_draw_message = function () {\n",
439       "    if (!this.waiting) {\n",
440       "        this.waiting = true;\n",
441       "        this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
442       "    }\n",
443       "};\n",
444       "\n",
445       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
446       "    var format_dropdown = fig.format_dropdown;\n",
447       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
448       "    fig.ondownload(fig, format);\n",
449       "};\n",
450       "\n",
451       "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
452       "    var size = msg['size'];\n",
453       "    if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
454       "        fig._resize_canvas(size[0], size[1], msg['forward']);\n",
455       "        fig.send_message('refresh', {});\n",
456       "    }\n",
457       "};\n",
458       "\n",
459       "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
460       "    var x0 = msg['x0'] / fig.ratio;\n",
461       "    var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
462       "    var x1 = msg['x1'] / fig.ratio;\n",
463       "    var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
464       "    x0 = Math.floor(x0) + 0.5;\n",
465       "    y0 = Math.floor(y0) + 0.5;\n",
466       "    x1 = Math.floor(x1) + 0.5;\n",
467       "    y1 = Math.floor(y1) + 0.5;\n",
468       "    var min_x = Math.min(x0, x1);\n",
469       "    var min_y = Math.min(y0, y1);\n",
470       "    var width = Math.abs(x1 - x0);\n",
471       "    var height = Math.abs(y1 - y0);\n",
472       "\n",
473       "    fig.rubberband_context.clearRect(\n",
474       "        0,\n",
475       "        0,\n",
476       "        fig.canvas.width / fig.ratio,\n",
477       "        fig.canvas.height / fig.ratio\n",
478       "    );\n",
479       "\n",
480       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
481       "};\n",
482       "\n",
483       "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
484       "    // Updates the figure title.\n",
485       "    fig.header.textContent = msg['label'];\n",
486       "};\n",
487       "\n",
488       "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
489       "    var cursor = msg['cursor'];\n",
490       "    switch (cursor) {\n",
491       "        case 0:\n",
492       "            cursor = 'pointer';\n",
493       "            break;\n",
494       "        case 1:\n",
495       "            cursor = 'default';\n",
496       "            break;\n",
497       "        case 2:\n",
498       "            cursor = 'crosshair';\n",
499       "            break;\n",
500       "        case 3:\n",
501       "            cursor = 'move';\n",
502       "            break;\n",
503       "    }\n",
504       "    fig.rubberband_canvas.style.cursor = cursor;\n",
505       "};\n",
506       "\n",
507       "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
508       "    fig.message.textContent = msg['message'];\n",
509       "};\n",
510       "\n",
511       "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
512       "    // Request the server to send over a new figure.\n",
513       "    fig.send_draw_message();\n",
514       "};\n",
515       "\n",
516       "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
517       "    fig.image_mode = msg['mode'];\n",
518       "};\n",
519       "\n",
520       "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
521       "    for (var key in msg) {\n",
522       "        if (!(key in fig.buttons)) {\n",
523       "            continue;\n",
524       "        }\n",
525       "        fig.buttons[key].disabled = !msg[key];\n",
526       "        fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
527       "    }\n",
528       "};\n",
529       "\n",
530       "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
531       "    if (msg['mode'] === 'PAN') {\n",
532       "        fig.buttons['Pan'].classList.add('active');\n",
533       "        fig.buttons['Zoom'].classList.remove('active');\n",
534       "    } else if (msg['mode'] === 'ZOOM') {\n",
535       "        fig.buttons['Pan'].classList.remove('active');\n",
536       "        fig.buttons['Zoom'].classList.add('active');\n",
537       "    } else {\n",
538       "        fig.buttons['Pan'].classList.remove('active');\n",
539       "        fig.buttons['Zoom'].classList.remove('active');\n",
540       "    }\n",
541       "};\n",
542       "\n",
543       "mpl.figure.prototype.updated_canvas_event = function () {\n",
544       "    // Called whenever the canvas gets updated.\n",
545       "    this.send_message('ack', {});\n",
546       "};\n",
547       "\n",
548       "// A function to construct a web socket function for onmessage handling.\n",
549       "// Called in the figure constructor.\n",
550       "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
551       "    return function socket_on_message(evt) {\n",
552       "        if (evt.data instanceof Blob) {\n",
553       "            /* FIXME: We get \"Resource interpreted as Image but\n",
554       "             * transferred with MIME type text/plain:\" errors on\n",
555       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
556       "             * to be part of the websocket stream */\n",
557       "            evt.data.type = 'image/png';\n",
558       "\n",
559       "            /* Free the memory for the previous frames */\n",
560       "            if (fig.imageObj.src) {\n",
561       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
562       "                    fig.imageObj.src\n",
563       "                );\n",
564       "            }\n",
565       "\n",
566       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
567       "                evt.data\n",
568       "            );\n",
569       "            fig.updated_canvas_event();\n",
570       "            fig.waiting = false;\n",
571       "            return;\n",
572       "        } else if (\n",
573       "            typeof evt.data === 'string' &&\n",
574       "            evt.data.slice(0, 21) === 'data:image/png;base64'\n",
575       "        ) {\n",
576       "            fig.imageObj.src = evt.data;\n",
577       "            fig.updated_canvas_event();\n",
578       "            fig.waiting = false;\n",
579       "            return;\n",
580       "        }\n",
581       "\n",
582       "        var msg = JSON.parse(evt.data);\n",
583       "        var msg_type = msg['type'];\n",
584       "\n",
585       "        // Call the  \"handle_{type}\" callback, which takes\n",
586       "        // the figure and JSON message as its only arguments.\n",
587       "        try {\n",
588       "            var callback = fig['handle_' + msg_type];\n",
589       "        } catch (e) {\n",
590       "            console.log(\n",
591       "                \"No handler for the '\" + msg_type + \"' message type: \",\n",
592       "                msg\n",
593       "            );\n",
594       "            return;\n",
595       "        }\n",
596       "\n",
597       "        if (callback) {\n",
598       "            try {\n",
599       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
600       "                callback(fig, msg);\n",
601       "            } catch (e) {\n",
602       "                console.log(\n",
603       "                    \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
604       "                    e,\n",
605       "                    e.stack,\n",
606       "                    msg\n",
607       "                );\n",
608       "            }\n",
609       "        }\n",
610       "    };\n",
611       "};\n",
612       "\n",
613       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
614       "mpl.findpos = function (e) {\n",
615       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
616       "    var targ;\n",
617       "    if (!e) {\n",
618       "        e = window.event;\n",
619       "    }\n",
620       "    if (e.target) {\n",
621       "        targ = e.target;\n",
622       "    } else if (e.srcElement) {\n",
623       "        targ = e.srcElement;\n",
624       "    }\n",
625       "    if (targ.nodeType === 3) {\n",
626       "        // defeat Safari bug\n",
627       "        targ = targ.parentNode;\n",
628       "    }\n",
629       "\n",
630       "    // pageX,Y are the mouse positions relative to the document\n",
631       "    var boundingRect = targ.getBoundingClientRect();\n",
632       "    var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
633       "    var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
634       "\n",
635       "    return { x: x, y: y };\n",
636       "};\n",
637       "\n",
638       "/*\n",
639       " * return a copy of an object with only non-object keys\n",
640       " * we need this to avoid circular references\n",
641       " * http://stackoverflow.com/a/24161582/3208463\n",
642       " */\n",
643       "function simpleKeys(original) {\n",
644       "    return Object.keys(original).reduce(function (obj, key) {\n",
645       "        if (typeof original[key] !== 'object') {\n",
646       "            obj[key] = original[key];\n",
647       "        }\n",
648       "        return obj;\n",
649       "    }, {});\n",
650       "}\n",
651       "\n",
652       "mpl.figure.prototype.mouse_event = function (event, name) {\n",
653       "    var canvas_pos = mpl.findpos(event);\n",
654       "\n",
655       "    if (name === 'button_press') {\n",
656       "        this.canvas.focus();\n",
657       "        this.canvas_div.focus();\n",
658       "    }\n",
659       "\n",
660       "    var x = canvas_pos.x * this.ratio;\n",
661       "    var y = canvas_pos.y * this.ratio;\n",
662       "\n",
663       "    this.send_message(name, {\n",
664       "        x: x,\n",
665       "        y: y,\n",
666       "        button: event.button,\n",
667       "        step: event.step,\n",
668       "        guiEvent: simpleKeys(event),\n",
669       "    });\n",
670       "\n",
671       "    /* This prevents the web browser from automatically changing to\n",
672       "     * the text insertion cursor when the button is pressed.  We want\n",
673       "     * to control all of the cursor setting manually through the\n",
674       "     * 'cursor' event from matplotlib */\n",
675       "    event.preventDefault();\n",
676       "    return false;\n",
677       "};\n",
678       "\n",
679       "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
680       "    // Handle any extra behaviour associated with a key event\n",
681       "};\n",
682       "\n",
683       "mpl.figure.prototype.key_event = function (event, name) {\n",
684       "    // Prevent repeat events\n",
685       "    if (name === 'key_press') {\n",
686       "        if (event.which === this._key) {\n",
687       "            return;\n",
688       "        } else {\n",
689       "            this._key = event.which;\n",
690       "        }\n",
691       "    }\n",
692       "    if (name === 'key_release') {\n",
693       "        this._key = null;\n",
694       "    }\n",
695       "\n",
696       "    var value = '';\n",
697       "    if (event.ctrlKey && event.which !== 17) {\n",
698       "        value += 'ctrl+';\n",
699       "    }\n",
700       "    if (event.altKey && event.which !== 18) {\n",
701       "        value += 'alt+';\n",
702       "    }\n",
703       "    if (event.shiftKey && event.which !== 16) {\n",
704       "        value += 'shift+';\n",
705       "    }\n",
706       "\n",
707       "    value += 'k';\n",
708       "    value += event.which.toString();\n",
709       "\n",
710       "    this._key_event_extra(event, name);\n",
711       "\n",
712       "    this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
713       "    return false;\n",
714       "};\n",
715       "\n",
716       "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
717       "    if (name === 'download') {\n",
718       "        this.handle_save(this, null);\n",
719       "    } else {\n",
720       "        this.send_message('toolbar_button', { name: name });\n",
721       "    }\n",
722       "};\n",
723       "\n",
724       "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
725       "    this.message.textContent = tooltip;\n",
726       "};\n",
727       "\n",
728       "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
729       "// prettier-ignore\n",
730       "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",
731       "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",
732       "\n",
733       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
734       "\n",
735       "mpl.default_extension = \"png\";/* global mpl */\n",
736       "\n",
737       "var comm_websocket_adapter = function (comm) {\n",
738       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
739       "    // object with the appropriate methods. Currently this is a non binary\n",
740       "    // socket, so there is still some room for performance tuning.\n",
741       "    var ws = {};\n",
742       "\n",
743       "    ws.close = function () {\n",
744       "        comm.close();\n",
745       "    };\n",
746       "    ws.send = function (m) {\n",
747       "        //console.log('sending', m);\n",
748       "        comm.send(m);\n",
749       "    };\n",
750       "    // Register the callback with on_msg.\n",
751       "    comm.on_msg(function (msg) {\n",
752       "        //console.log('receiving', msg['content']['data'], msg);\n",
753       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
754       "        ws.onmessage(msg['content']['data']);\n",
755       "    });\n",
756       "    return ws;\n",
757       "};\n",
758       "\n",
759       "mpl.mpl_figure_comm = function (comm, msg) {\n",
760       "    // This is the function which gets called when the mpl process\n",
761       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
762       "\n",
763       "    var id = msg.content.data.id;\n",
764       "    // Get hold of the div created by the display call when the Comm\n",
765       "    // socket was opened in Python.\n",
766       "    var element = document.getElementById(id);\n",
767       "    var ws_proxy = comm_websocket_adapter(comm);\n",
768       "\n",
769       "    function ondownload(figure, _format) {\n",
770       "        window.open(figure.canvas.toDataURL());\n",
771       "    }\n",
772       "\n",
773       "    var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
774       "\n",
775       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
776       "    // web socket which is closed, not our websocket->open comm proxy.\n",
777       "    ws_proxy.onopen();\n",
778       "\n",
779       "    fig.parent_element = element;\n",
780       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
781       "    if (!fig.cell_info) {\n",
782       "        console.error('Failed to find cell for figure', id, fig);\n",
783       "        return;\n",
784       "    }\n",
785       "    fig.cell_info[0].output_area.element.on(\n",
786       "        'cleared',\n",
787       "        { fig: fig },\n",
788       "        fig._remove_fig_handler\n",
789       "    );\n",
790       "};\n",
791       "\n",
792       "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
793       "    var width = fig.canvas.width / fig.ratio;\n",
794       "    fig.cell_info[0].output_area.element.off(\n",
795       "        'cleared',\n",
796       "        fig._remove_fig_handler\n",
797       "    );\n",
798       "    fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
799       "\n",
800       "    // Update the output cell to use the data from the current canvas.\n",
801       "    fig.push_to_output();\n",
802       "    var dataURL = fig.canvas.toDataURL();\n",
803       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
804       "    // the notebook keyboard shortcuts fail.\n",
805       "    IPython.keyboard_manager.enable();\n",
806       "    fig.parent_element.innerHTML =\n",
807       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
808       "    fig.close_ws(fig, msg);\n",
809       "};\n",
810       "\n",
811       "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
812       "    fig.send_message('closing', msg);\n",
813       "    // fig.ws.close()\n",
814       "};\n",
815       "\n",
816       "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
817       "    // Turn the data on the canvas into data in the output cell.\n",
818       "    var width = this.canvas.width / this.ratio;\n",
819       "    var dataURL = this.canvas.toDataURL();\n",
820       "    this.cell_info[1]['text/html'] =\n",
821       "        '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
822       "};\n",
823       "\n",
824       "mpl.figure.prototype.updated_canvas_event = function () {\n",
825       "    // Tell IPython that the notebook contents must change.\n",
826       "    IPython.notebook.set_dirty(true);\n",
827       "    this.send_message('ack', {});\n",
828       "    var fig = this;\n",
829       "    // Wait a second, then push the new image to the DOM so\n",
830       "    // that it is saved nicely (might be nice to debounce this).\n",
831       "    setTimeout(function () {\n",
832       "        fig.push_to_output();\n",
833       "    }, 1000);\n",
834       "};\n",
835       "\n",
836       "mpl.figure.prototype._init_toolbar = function () {\n",
837       "    var fig = this;\n",
838       "\n",
839       "    var toolbar = document.createElement('div');\n",
840       "    toolbar.classList = 'btn-toolbar';\n",
841       "    this.root.appendChild(toolbar);\n",
842       "\n",
843       "    function on_click_closure(name) {\n",
844       "        return function (_event) {\n",
845       "            return fig.toolbar_button_onclick(name);\n",
846       "        };\n",
847       "    }\n",
848       "\n",
849       "    function on_mouseover_closure(tooltip) {\n",
850       "        return function (event) {\n",
851       "            if (!event.currentTarget.disabled) {\n",
852       "                return fig.toolbar_button_onmouseover(tooltip);\n",
853       "            }\n",
854       "        };\n",
855       "    }\n",
856       "\n",
857       "    fig.buttons = {};\n",
858       "    var buttonGroup = document.createElement('div');\n",
859       "    buttonGroup.classList = 'btn-group';\n",
860       "    var button;\n",
861       "    for (var toolbar_ind in mpl.toolbar_items) {\n",
862       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
863       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
864       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
865       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
866       "\n",
867       "        if (!name) {\n",
868       "            /* Instead of a spacer, we start a new button group. */\n",
869       "            if (buttonGroup.hasChildNodes()) {\n",
870       "                toolbar.appendChild(buttonGroup);\n",
871       "            }\n",
872       "            buttonGroup = document.createElement('div');\n",
873       "            buttonGroup.classList = 'btn-group';\n",
874       "            continue;\n",
875       "        }\n",
876       "\n",
877       "        button = fig.buttons[name] = document.createElement('button');\n",
878       "        button.classList = 'btn btn-default';\n",
879       "        button.href = '#';\n",
880       "        button.title = name;\n",
881       "        button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
882       "        button.addEventListener('click', on_click_closure(method_name));\n",
883       "        button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
884       "        buttonGroup.appendChild(button);\n",
885       "    }\n",
886       "\n",
887       "    if (buttonGroup.hasChildNodes()) {\n",
888       "        toolbar.appendChild(buttonGroup);\n",
889       "    }\n",
890       "\n",
891       "    // Add the status bar.\n",
892       "    var status_bar = document.createElement('span');\n",
893       "    status_bar.classList = 'mpl-message pull-right';\n",
894       "    toolbar.appendChild(status_bar);\n",
895       "    this.message = status_bar;\n",
896       "\n",
897       "    // Add the close button to the window.\n",
898       "    var buttongrp = document.createElement('div');\n",
899       "    buttongrp.classList = 'btn-group inline pull-right';\n",
900       "    button = document.createElement('button');\n",
901       "    button.classList = 'btn btn-mini btn-primary';\n",
902       "    button.href = '#';\n",
903       "    button.title = 'Stop Interaction';\n",
904       "    button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
905       "    button.addEventListener('click', function (_evt) {\n",
906       "        fig.handle_close(fig, {});\n",
907       "    });\n",
908       "    button.addEventListener(\n",
909       "        'mouseover',\n",
910       "        on_mouseover_closure('Stop Interaction')\n",
911       "    );\n",
912       "    buttongrp.appendChild(button);\n",
913       "    var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
914       "    titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
915       "};\n",
916       "\n",
917       "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
918       "    var fig = event.data.fig;\n",
919       "    if (event.target !== this) {\n",
920       "        // Ignore bubbled events from children.\n",
921       "        return;\n",
922       "    }\n",
923       "    fig.close_ws(fig, {});\n",
924       "};\n",
925       "\n",
926       "mpl.figure.prototype._root_extra_style = function (el) {\n",
927       "    el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
928       "};\n",
929       "\n",
930       "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
931       "    // this is important to make the div 'focusable\n",
932       "    el.setAttribute('tabindex', 0);\n",
933       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
934       "    // off when our div gets focus\n",
935       "\n",
936       "    // location in version 3\n",
937       "    if (IPython.notebook.keyboard_manager) {\n",
938       "        IPython.notebook.keyboard_manager.register_events(el);\n",
939       "    } else {\n",
940       "        // location in version 2\n",
941       "        IPython.keyboard_manager.register_events(el);\n",
942       "    }\n",
943       "};\n",
944       "\n",
945       "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
946       "    var manager = IPython.notebook.keyboard_manager;\n",
947       "    if (!manager) {\n",
948       "        manager = IPython.keyboard_manager;\n",
949       "    }\n",
950       "\n",
951       "    // Check for shift+enter\n",
952       "    if (event.shiftKey && event.which === 13) {\n",
953       "        this.canvas_div.blur();\n",
954       "        // select the cell after this one\n",
955       "        var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
956       "        IPython.notebook.select(index + 1);\n",
957       "    }\n",
958       "};\n",
959       "\n",
960       "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
961       "    fig.ondownload(fig, null);\n",
962       "};\n",
963       "\n",
964       "mpl.find_output_cell = function (html_output) {\n",
965       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
966       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
967       "    // IPython event is triggered only after the cells have been serialised, which for\n",
968       "    // our purposes (turning an active figure into a static one), is too late.\n",
969       "    var cells = IPython.notebook.get_cells();\n",
970       "    var ncells = cells.length;\n",
971       "    for (var i = 0; i < ncells; i++) {\n",
972       "        var cell = cells[i];\n",
973       "        if (cell.cell_type === 'code') {\n",
974       "            for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
975       "                var data = cell.output_area.outputs[j];\n",
976       "                if (data.data) {\n",
977       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
978       "                    data = data.data;\n",
979       "                }\n",
980       "                if (data['text/html'] === html_output) {\n",
981       "                    return [cell, data, j];\n",
982       "                }\n",
983       "            }\n",
984       "        }\n",
985       "    }\n",
986       "};\n",
987       "\n",
988       "// Register the function which deals with the matplotlib target/channel.\n",
989       "// The kernel may be null if the page has been refreshed.\n",
990       "if (IPython.notebook.kernel !== null) {\n",
991       "    IPython.notebook.kernel.comm_manager.register_target(\n",
992       "        'matplotlib',\n",
993       "        mpl.mpl_figure_comm\n",
994       "    );\n",
995       "}\n"
996      ],
997      "text/plain": [
998       "<IPython.core.display.Javascript object>"
999      ]
1000     },
1001     "metadata": {},
1002     "output_type": "display_data"
1003    },
1004    {
1005     "data": {
1006      "text/html": [
1007       "<img src=\"data:image/png;base64,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\" width=\"450\">"
1008      ],
1009      "text/plain": [
1010       "<IPython.core.display.HTML object>"
1011      ]
1012     },
1013     "metadata": {},
1014     "output_type": "display_data"
1015    }
1016   ],
1017   "source": [
1018    "plt.figure(figsize=(4.5,3))\n",
1019    "plt.semilogy(err_apophis[:,0], err_apophis[:,1], 'C7.', label=\"Position error (m)\")\n",
1020    "plt.semilogy(err_apophis[:,0], err_apophis[:,2], 'k.', label=\"Velocity error (m/s)\")\n",
1021    "plt.xlabel(\"Time to close approach (years)\")\n",
1022    "plt.ylabel(\"Error (see legend)\")\n",
1023    "plt.legend()\n",
1024    "plt.tight_layout()"
1025   ]
1026  },
1027  {
1028   "cell_type": "code",
1029   "execution_count": 28,
1030   "metadata": {},
1031   "outputs": [],
1032   "source": [
1033    "plt.savefig(\"apophis.png\", dpi = 600)"
1034   ]
1035  },
1036  {
1037   "cell_type": "code",
1038   "execution_count": null,
1039   "metadata": {},
1040   "outputs": [],
1041   "source": []
1042  },
1043  {
1044   "cell_type": "code",
1045   "execution_count": null,
1046   "metadata": {},
1047   "outputs": [],
1048   "source": []
1049  }
1050 ],
1051 "metadata": {
1052  "kernelspec": {
1053   "display_name": "Python 3",
1054   "language": "python",
1055   "name": "python3"
1056  },
1057  "language_info": {
1058   "codemirror_mode": {
1059    "name": "ipython",
1060    "version": 3
1061   },
1062   "file_extension": ".py",
1063   "mimetype": "text/x-python",
1064   "name": "python",
1065   "nbconvert_exporter": "python",
1066   "pygments_lexer": "ipython3",
1067   "version": "3.8.6"
1068  }
1069 },
1070 "nbformat": 4,
1071 "nbformat_minor": 4
1072}
1073