diff --git a/posts/duffing.ipynb b/posts/duffing.ipynb index f171248..1f45b1c 100644 --- a/posts/duffing.ipynb +++ b/posts/duffing.ipynb @@ -11,7 +11,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2020-12-29T11:27:25.734Z", @@ -22,7 +22,6 @@ }, "outputs": [], "source": [ - "%matplotlib notebook\n", "import numpy as np\n", "from scipy.integrate import solve_ivp\n", "import matplotlib.pyplot as plt\n", @@ -31,10 +30,18 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ + "alpha = -1\n", + "beta = 1\n", + "gamma = 0.1\n", + "omega = 1.4\n", + "# interesting values for epsilon: 0.1, 0.4, 1.0\n", + "epsilon = 0.4\n", + "\n", + "\n", "def V(x):\n", " return alpha * x ** 2 / 2 + beta * x ** 4 / 4\n", "\n", @@ -47,26 +54,14 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { - "application/javascript": "/* Put everything inside the global mpl namespace */\n/* global mpl */\nwindow.mpl = {};\n\nmpl.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\nmpl.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\nmpl.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\nmpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n\nmpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.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\nmpl.figure.prototype.handle_figure_label = function (fig, msg) {\n // Updates the figure title.\n fig.header.textContent = msg['label'];\n};\n\nmpl.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\nmpl.figure.prototype.handle_message = function (fig, msg) {\n fig.message.textContent = msg['message'];\n};\n\nmpl.figure.prototype.handle_draw = function (fig, _msg) {\n // Request the server to send over a new figure.\n fig.send_draw_message();\n};\n\nmpl.figure.prototype.handle_image_mode = function (fig, msg) {\n fig.image_mode = msg['mode'];\n};\n\nmpl.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\nmpl.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\nmpl.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.\nmpl.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\nmpl.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 */\nfunction 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\nmpl.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\nmpl.figure.prototype._key_event_extra = function (_event, _name) {\n // Handle any extra behaviour associated with a key event\n};\n\nmpl.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\nmpl.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\nmpl.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\nvar _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\nmpl.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\nmpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n\nmpl.default_extension = \"png\";/* global mpl */\n\nvar 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\nmpl.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(\"
\");\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\nmpl.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 '';\n fig.close_ws(fig, msg);\n};\n\nmpl.figure.prototype.close_ws = function (fig, msg) {\n fig.send_message('closing', msg);\n // fig.ws.close()\n};\n\nmpl.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 '';\n};\n\nmpl.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\nmpl.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 = '';\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 = '';\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\nmpl.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\nmpl.figure.prototype._root_extra_style = function (el) {\n el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n};\n\nmpl.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\nmpl.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\nmpl.figure.prototype.handle_save = function (fig, _msg) {\n fig.ondownload(fig, null);\n};\n\nmpl.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.\nif (IPython.notebook.kernel !== null) {\n IPython.notebook.kernel.comm_manager.register_target(\n 'matplotlib',\n mpl.mpl_figure_comm\n );\n}\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], + "image/png": "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uXORlZUldSj1xt/fH127dsVnn30GoORm5W5ubpgzZw7mz58vcXTSkslk2LlzJ0aOHCl1KER1qiG2dY9iu1c5fWz7eKWO9F5BQQFOnTqFgIAA1T65XI6AgABERkZKGBkRkWaw3WuYmNSR3rt16xaKi4vh5OSktt/JyQmpqakSRUVEpDls9xomJnU6bv78+ZDJZJVu8fHxUodJRFQrbOuInsxQ6gCodubNm4cpU6ZUWqZZs2b1E4yWsre3h4GBAdLS0tT2p6WlwdnZWaKoiKg62NZVD9u9holJnY5zcHCAg4OD1GFoNWNjY/j6+mLfvn2qAbFKpRL79u3D7NmzpQ2OiKqEbV31sN1rmJjUNSBJSUnIzMxEUlISiouLER0dDQBo0aIFLCwspA1Ow4KDgzF58mR06dIFfn5+WLlyJfLy8hAUFCR1aJK4e/cuLl++rHqckJCA6Oho2NnZoWnTphJGRlR7DbmtexTbvbL0vu0T1GBMnjxZACizRURESB1avVi1apVo2rSpMDY2Fn5+fuLo0aNShySZiIiIcn8XJk+eLHVoRLXW0Nu6R7HdU6fvbR/XqSMiIiLSA5z9SkRERKQHmNQRERER6QEmdURERER6gEkdERERkR5gUkdERESkB5jUEREREekBJnVEREREeoBJHREREZEeYFJHREREpAeY1BERERHpASZ1pPc2b94MU1NTpKSkqPYFBQWhY8eOyM7OljAyIiLNYLvXMPHer6T3hBDw8fFB7969sWrVKixcuBDr16/H0aNH0bhxY6nDIyKqc2z3GiZDqQMg0jSZTIalS5di9OjRcHZ2xqpVq3Dw4EE2bESkt9juNUy8UkcNRufOnRETE4M///wTffr0kTocIiKNY7vXsHBMHTUIu3fvRnx8PIqLi+Hk5CR1OEREGsd2r+HhlTrSe1FRUejbty+++OILhIeHw8rKCtu2bZM6LCIijWG71zBxTB3ptcTERAwZMgTvvPMOJkyYgGbNmqF79+6IiopC586dpQ6PiKjOsd1ruHiljvRWZmYmevTogb59+2Lt2rWq/UOGDEFxcTF2794tYXRERHWP7V7DxqSOiIiISA9wogQRERGRHmBSR0RERKQHmNQRERER6QEmdURERER6gEkdERERkR5gUkdERESkB5jUEREREekBJnVEREREeoBJHREREZEeYFJHREREpAeY1BER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gK1btyI4OBgLFy5EVFQUvL29ERgYiPT09AqPsbKyQkpKimq7du1aPUZMRPWNSR0RkQ746KOPMH36dAQFBcHLywtr166FmZkZ1q9fX+ExMpkMzs7Oqs3JyanCsvn5+cjJyVHbiEi3MKkjItJyBQUFOHXqFAICAlT75HI5AgICEBkZWeFxd+/ehbu7O9zc3DBixAjExMRUWDYsLAzW1taqzc3NrU7rQESax6SOiEjL3bp1C8XFxWWutDk5OSE1NbXcY1q3bo3169fjp59+wnfffQelUokePXrg+vXr5ZYPCQlBdna2aktOTq7zehCRZjWYdeqIiBqS7t27o3v37qrHPXr0QNu2bfHFF19gyZIlZcorFAooFIr6DJGI6hiv1BERaTl7e3sYGBggLS1NbX9aWhqcnZ2r9BpGRkbo1KmT2u0SiUi/MKkjItJyxsbG8PX1xb59+1T7lEol9u3bp3Y1rjLFxcU4d+4cXFxcNBUmEUmM3a9ERDogODgYkydPRpcuXeDn54eVK1ciLy8PQUFBAIBJkyahcePGCAsLAwAsXrwY3bp1Q4sWLZCVlYXly5fj2rVrmDZtmpTVICINYlJHRKQDxo0bh4yMDCxYsACpqanw8fHB7t27VZMnkpKSIJf/2/ly584dTJ8+HampqbC1tYWvry+OHDkCLy8vqapARBomE7zLfZXk5OTA2toa2dnZsLKykjocogaL52L94OdMpD2qej5yTB0RERGRHmBSR0RERKQHmNQRERER6QEmdURERER6gEkdERERkR5gUkdERESkB5jUEREREekBJnVEREREeoBJHREREZEeYFJHREREpAeY1BERERHpASZ1RERERHqASR0RERGRHmBSR0RERKQHmNQRERER6QEmdURERER6gEkdERERkR5gUkdERESkB5jUEREREekBJnVEREREeoBJHREREZEeMJQ6ACIiIqp7olgg62AWClIKYOxiDJteNpAZyKQOizSoQV2pW716NTw8PGBiYgJ/f38cP35c6pCIiKqsum3Ytm3b0KZNG5iYmKBDhw74/fff6ylSklrGjgwc9TiKM/3OIO75OJzpdwZHPY4iY0eG1KGRBtVrUpebm1ufb6dm69atCA4OxsKFCxEVFQVvb28EBgYiPT1dspiISHdI2X4B1W/Djhw5ggkTJmDq1Kk4ffo0Ro4ciZEjR+L8+fP1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", "text/plain": [ - "" + "
" ] }, "metadata": {}, @@ -75,16 +70,10 @@ ], "source": [ "# solve equation of motion\n", - "alpha = -1\n", - "beta = 1\n", - "gamma = 0.1\n", - "omega = 1.4\n", - "# interesting values for epsilon: 0.1, 0.4, 1.0\n", - "epsilon = 0.4\n", "\n", "x0, v0 = 0, 0\n", "n_samples_per_period = 50\n", - "n_period = 5000\n", + "n_period = 100\n", "period = 2 * np.pi / omega\n", "tmax = n_period * period\n", "\n", @@ -137,33 +126,33 @@ "plt.tight_layout()\n", "\n", "def animate(i): \n", - " ln1.set_data(x[i], V(x[i]))\n", + " ln1.set_data([x[i]], [V(x[i])])\n", " j = max(0, i - 10 * n_samples_per_period)\n", " sl = slice(j, i+1)\n", " ln2.set_data(t[sl], x[sl])\n", " ax2.set_xlim(t[j], t[i+1])\n", " sl = slice(0, i+1)\n", " ln3.set_data(x[sl], xdot[sl])\n", - " ln3a.set_data(x[i], xdot[i])\n", + " ln3a.set_data([x[i]], [xdot[i]])\n", " return (ln1, ln2, ln3, ln3a)\n", "\n", "anim = animation.FuncAnimation(fig, animate, frames=len(x), interval=2)" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], - "source": [] + "source": [ + "To see the animation in action, run this code in a Jupyter notebook and prepend the `%matplotlib notebook` to the first cell." + ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { - "display_name": "py38", + "display_name": ".venv", "language": "python", - "name": "py38" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -175,7 +164,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.6" + "version": "3.12.3" }, "nteract": { "version": "0.27.0"