From 39bea86716f5667ce470fb31bcf078a6c629936d Mon Sep 17 00:00:00 2001 From: crzdg Date: Sat, 15 Apr 2023 09:33:05 +0000 Subject: [PATCH 1/4] Fix notebook and set eom for disc --- frispy/disc.py | 3 + notebooks/Visualizing Trajectories.ipynb | 340 ++++++++++++----------- 2 files changed, 184 insertions(+), 159 deletions(-) diff --git a/frispy/disc.py b/frispy/disc.py index 71f35d9..e952e55 100644 --- a/frispy/disc.py +++ b/frispy/disc.py @@ -64,6 +64,7 @@ class Disc: air_density: float = 1.225 # kg / m ^ 3 g: float = 9.81 # m / s ^ 2 model: Model = Model() + eom: EOM = None eom_class: Type = EOM def compute_trajectory( @@ -138,6 +139,8 @@ def compute_trajectory( **solver_kwargs, ) + self.eom = eom + return ( { "times": result.t, diff --git a/notebooks/Visualizing Trajectories.ipynb b/notebooks/Visualizing Trajectories.ipynb index 1c338cc..9700fd6 100644 --- a/notebooks/Visualizing Trajectories.ipynb +++ b/notebooks/Visualizing Trajectories.ipynb @@ -19,7 +19,7 @@ "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", - "from frispy import Disc\n", + "from frispy.disc import Disc\n", "%matplotlib inline\n", "%matplotlib notebook\n", "plt.rc(\"font\", size=14, family=\"serif\")" @@ -44,7 +44,7 @@ "metadata": {}, "outputs": [], "source": [ - "result1 = disc1.compute_trajectory(flight_time=4)" + "result1, _ = disc1.compute_trajectory(flight_time=4)" ] }, { @@ -54,14 +54,16 @@ "metadata": {}, "outputs": [], "source": [ - "result2 = disc2.compute_trajectory(flight_time=4)" + "result2, _ = disc2.compute_trajectory(flight_time=4)" ] }, { "cell_type": "code", "execution_count": 5, "id": "3f0cf27c", - "metadata": {}, + "metadata": { + "scrolled": false + }, "outputs": [ { "data": { @@ -131,7 +133,9 @@ " 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", + " fig.send_message('set_device_pixel_ratio', {\n", + " device_pixel_ratio: fig.ratio,\n", + " });\n", " }\n", " fig.send_message('refresh', {});\n", " };\n", @@ -178,6 +182,7 @@ " var fig = this;\n", "\n", " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute('tabindex', '0');\n", " canvas_div.setAttribute(\n", " 'style',\n", " 'border: 1px solid #ddd;' +\n", @@ -188,7 +193,8 @@ " 'outline: 0;' +\n", " 'overflow: hidden;' +\n", " 'position: relative;' +\n", - " 'resize: both;'\n", + " 'resize: both;' +\n", + " 'z-index: 2;'\n", " );\n", "\n", " function on_keyboard_event_closure(name) {\n", @@ -211,7 +217,13 @@ "\n", " var canvas = (this.canvas = document.createElement('canvas'));\n", " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'pointer-events: none;' +\n", + " 'position: relative;' +\n", + " 'z-index: 0;'\n", + " );\n", "\n", " this.context = canvas.getContext('2d');\n", "\n", @@ -231,7 +243,12 @@ " ));\n", " rubberband_canvas.setAttribute(\n", " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", + " 'box-sizing: content-box;' +\n", + " 'left: 0;' +\n", + " 'pointer-events: none;' +\n", + " 'position: absolute;' +\n", + " 'top: 0;' +\n", + " 'z-index: 1;'\n", " );\n", "\n", " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", @@ -281,10 +298,10 @@ " 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", + " /* This rescales the canvas back to display pixels, so that it\n", + " * appears correct on HiDPI screens. */\n", + " canvas.style.width = width + 'px';\n", + " canvas.style.height = height + 'px';\n", "\n", " rubberband_canvas.setAttribute('width', width);\n", " rubberband_canvas.setAttribute('height', height);\n", @@ -300,34 +317,53 @@ " 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", + " /* User Agent sniffing is bad, but WebKit is busted:\n", + " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", + " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", + " * The worst that happens here is that they get an extra browser\n", + " * selection when dragging, if this check fails to catch them.\n", + " */\n", + " var UA = navigator.userAgent;\n", + " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", + " if(isWebKit) {\n", + " return function (event) {\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We\n", + " * want to control all of the cursor setting manually through\n", + " * the 'cursor' event from matplotlib */\n", + " event.preventDefault()\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " } else {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", " }\n", "\n", - " rubberband_canvas.addEventListener(\n", + " canvas_div.addEventListener(\n", " 'mousedown',\n", " on_mouse_event_closure('button_press')\n", " );\n", - " rubberband_canvas.addEventListener(\n", + " canvas_div.addEventListener(\n", " 'mouseup',\n", " on_mouse_event_closure('button_release')\n", " );\n", - " rubberband_canvas.addEventListener(\n", + " canvas_div.addEventListener(\n", " 'dblclick',\n", " on_mouse_event_closure('dblclick')\n", " );\n", " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", + " canvas_div.addEventListener(\n", " 'mousemove',\n", " on_mouse_event_closure('motion_notify')\n", " );\n", "\n", - " rubberband_canvas.addEventListener(\n", + " canvas_div.addEventListener(\n", " 'mouseenter',\n", " on_mouse_event_closure('figure_enter')\n", " );\n", - " rubberband_canvas.addEventListener(\n", + " canvas_div.addEventListener(\n", " 'mouseleave',\n", " on_mouse_event_closure('figure_leave')\n", " );\n", @@ -355,7 +391,7 @@ " };\n", "\n", " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", + " canvas_div.addEventListener('contextmenu', function (_e) {\n", " event.preventDefault();\n", " return false;\n", " });\n", @@ -510,22 +546,7 @@ "};\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", + " fig.canvas_div.style.cursor = msg['cursor'];\n", "};\n", "\n", "mpl.figure.prototype.handle_message = function (fig, msg) {\n", @@ -637,35 +658,27 @@ " };\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", + "function getModifiers(event) {\n", + " var mods = [];\n", + " if (event.ctrlKey) {\n", + " mods.push('ctrl');\n", " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", + " if (event.altKey) {\n", + " mods.push('alt');\n", " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", + " if (event.shiftKey) {\n", + " mods.push('shift');\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", + " if (event.metaKey) {\n", + " mods.push('meta');\n", + " }\n", + " return mods;\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", + " * https://stackoverflow.com/a/24161582/3208463\n", " */\n", "function simpleKeys(original) {\n", " return Object.keys(original).reduce(function (obj, key) {\n", @@ -677,29 +690,25 @@ "}\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", + " // from https://stackoverflow.com/q/1114465\n", + " var boundingRect = this.canvas.getBoundingClientRect();\n", + " var x = (event.clientX - boundingRect.left) * this.ratio;\n", + " var y = (event.clientY - boundingRect.top) * this.ratio;\n", "\n", " this.send_message(name, {\n", " x: x,\n", " y: y,\n", " button: event.button,\n", " step: event.step,\n", + " modifiers: getModifiers(event),\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", @@ -754,9 +763,9 @@ "///////////////// 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", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", "\n", "mpl.default_extension = \"png\";/* global mpl */\n", "\n", @@ -988,11 +997,6 @@ "};\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", @@ -1049,7 +1053,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -1064,9 +1068,9 @@ "plt.subplots_adjust(hspace=0.01)\n", "\n", "for res in [result1, result2]:\n", - " ax[0].plot(res.times, res.phi)\n", - " ax[1].plot(res.times, res.theta)\n", - " ax[2].plot(res.times, res.gamma)\n", + " ax[0].plot(res[\"times\"], res[\"phi\"])\n", + " ax[1].plot(res[\"times\"], res[\"theta\"])\n", + " ax[2].plot(res[\"times\"], res[\"gamma\"])\n", "\n", "ax[0].set_ylabel(r\"Azimuthal angle $\\phi$ [rad]\")\n", "ax[1].set_ylabel(r\"Polar angle $\\theta$ [rad]\")\n", @@ -1093,8 +1097,8 @@ } ], "source": [ - "phi = result2.phi[50]\n", - "theta = result2.theta[50]\n", + "phi = result2[\"phi\"][50]\n", + "theta = result2[\"theta\"][50]\n", "r = disc1.eom.rotation_matrix_from_phi_theta(phi, theta)\n", "print(r)" ] @@ -1192,7 +1196,9 @@ " 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", + " fig.send_message('set_device_pixel_ratio', {\n", + " device_pixel_ratio: fig.ratio,\n", + " });\n", " }\n", " fig.send_message('refresh', {});\n", " };\n", @@ -1239,6 +1245,7 @@ " var fig = this;\n", "\n", " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute('tabindex', '0');\n", " canvas_div.setAttribute(\n", " 'style',\n", " 'border: 1px solid #ddd;' +\n", @@ -1249,7 +1256,8 @@ " 'outline: 0;' +\n", " 'overflow: hidden;' +\n", " 'position: relative;' +\n", - " 'resize: both;'\n", + " 'resize: both;' +\n", + " 'z-index: 2;'\n", " );\n", "\n", " function on_keyboard_event_closure(name) {\n", @@ -1272,7 +1280,13 @@ "\n", " var canvas = (this.canvas = document.createElement('canvas'));\n", " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box;' +\n", + " 'pointer-events: none;' +\n", + " 'position: relative;' +\n", + " 'z-index: 0;'\n", + " );\n", "\n", " this.context = canvas.getContext('2d');\n", "\n", @@ -1292,7 +1306,12 @@ " ));\n", " rubberband_canvas.setAttribute(\n", " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", + " 'box-sizing: content-box;' +\n", + " 'left: 0;' +\n", + " 'pointer-events: none;' +\n", + " 'position: absolute;' +\n", + " 'top: 0;' +\n", + " 'z-index: 1;'\n", " );\n", "\n", " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", @@ -1342,10 +1361,10 @@ " 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", + " /* This rescales the canvas back to display pixels, so that it\n", + " * appears correct on HiDPI screens. */\n", + " canvas.style.width = width + 'px';\n", + " canvas.style.height = height + 'px';\n", "\n", " rubberband_canvas.setAttribute('width', width);\n", " rubberband_canvas.setAttribute('height', height);\n", @@ -1361,34 +1380,53 @@ " 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", + " /* User Agent sniffing is bad, but WebKit is busted:\n", + " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", + " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", + " * The worst that happens here is that they get an extra browser\n", + " * selection when dragging, if this check fails to catch them.\n", + " */\n", + " var UA = navigator.userAgent;\n", + " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", + " if(isWebKit) {\n", + " return function (event) {\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We\n", + " * want to control all of the cursor setting manually through\n", + " * the 'cursor' event from matplotlib */\n", + " event.preventDefault()\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " } else {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", " }\n", "\n", - " rubberband_canvas.addEventListener(\n", + " canvas_div.addEventListener(\n", " 'mousedown',\n", " on_mouse_event_closure('button_press')\n", " );\n", - " rubberband_canvas.addEventListener(\n", + " canvas_div.addEventListener(\n", " 'mouseup',\n", " on_mouse_event_closure('button_release')\n", " );\n", - " rubberband_canvas.addEventListener(\n", + " canvas_div.addEventListener(\n", " 'dblclick',\n", " on_mouse_event_closure('dblclick')\n", " );\n", " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", + " canvas_div.addEventListener(\n", " 'mousemove',\n", " on_mouse_event_closure('motion_notify')\n", " );\n", "\n", - " rubberband_canvas.addEventListener(\n", + " canvas_div.addEventListener(\n", " 'mouseenter',\n", " on_mouse_event_closure('figure_enter')\n", " );\n", - " rubberband_canvas.addEventListener(\n", + " canvas_div.addEventListener(\n", " 'mouseleave',\n", " on_mouse_event_closure('figure_leave')\n", " );\n", @@ -1416,7 +1454,7 @@ " };\n", "\n", " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", + " canvas_div.addEventListener('contextmenu', function (_e) {\n", " event.preventDefault();\n", " return false;\n", " });\n", @@ -1571,22 +1609,7 @@ "};\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", + " fig.canvas_div.style.cursor = msg['cursor'];\n", "};\n", "\n", "mpl.figure.prototype.handle_message = function (fig, msg) {\n", @@ -1698,35 +1721,27 @@ " };\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", + "function getModifiers(event) {\n", + " var mods = [];\n", + " if (event.ctrlKey) {\n", + " mods.push('ctrl');\n", " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", + " if (event.altKey) {\n", + " mods.push('alt');\n", " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", + " if (event.shiftKey) {\n", + " mods.push('shift');\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", + " if (event.metaKey) {\n", + " mods.push('meta');\n", + " }\n", + " return mods;\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", + " * https://stackoverflow.com/a/24161582/3208463\n", " */\n", "function simpleKeys(original) {\n", " return Object.keys(original).reduce(function (obj, key) {\n", @@ -1738,29 +1753,25 @@ "}\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", + " // from https://stackoverflow.com/q/1114465\n", + " var boundingRect = this.canvas.getBoundingClientRect();\n", + " var x = (event.clientX - boundingRect.left) * this.ratio;\n", + " var y = (event.clientY - boundingRect.top) * this.ratio;\n", "\n", " this.send_message(name, {\n", " x: x,\n", " y: y,\n", " button: event.button,\n", " step: event.step,\n", + " modifiers: getModifiers(event),\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", @@ -1815,9 +1826,9 @@ "///////////////// 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", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", "\n", "mpl.default_extension = \"png\";/* global mpl */\n", "\n", @@ -2049,11 +2060,6 @@ "};\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", @@ -2110,7 +2116,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -2123,10 +2129,10 @@ "source": [ "fig = plt.figure()\n", "ax = fig.add_subplot(projection=\"3d\")\n", - "ax.plot3D(result1.x, result1.y, result1.z, \"gray\")\n", - "ax.plot3D(result2.x, result2.y, result2.z, \"red\")\n", + "ax.plot3D(result1[\"x\"], result1[\"y\"], result1[\"z\"], \"gray\")\n", + "ax.plot3D(result2[\"x\"], result2[\"y\"], result2[\"z\"], \"red\")\n", "\n", - "ax.plot_trisurf(edge_T[:, 0] + result2.x[50], edge_T[:, 1] + result2.y[50], edge_T[:, 2] + result2.z[50])\n", + "ax.plot_trisurf(edge_T[:, 0] + result2[\"x\"][50], edge_T[:, 1] + result2[\"y\"][50], edge_T[:, 2] + result2[\"z\"][50])\n", "ax.set_xlim(0, 40)\n", "ax.set_ylim(-20, 20)\n", "ax.set_zlim(0, 10)\n", @@ -2141,6 +2147,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a418cdf2", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5677c446", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -2159,7 +2181,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.6" + "version": "3.10.6" } }, "nbformat": 4, From 8b1a58c04006a897fdca5c24dcbbc430eca7d603 Mon Sep 17 00:00:00 2001 From: crzdg Date: Sat, 15 Apr 2023 09:33:39 +0000 Subject: [PATCH 2/4] Use default_factory in dataclass This change is to introduce compatibility with Python 3.11 --- frispy/disc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frispy/disc.py b/frispy/disc.py index e952e55..5630ff2 100644 --- a/frispy/disc.py +++ b/frispy/disc.py @@ -1,6 +1,6 @@ """Disc class.""" -from dataclasses import dataclass +from dataclasses import dataclass, field from typing import Dict, Tuple, Type import numpy as np @@ -63,7 +63,7 @@ class Disc: mass: float = 0.175 # kg air_density: float = 1.225 # kg / m ^ 3 g: float = 9.81 # m / s ^ 2 - model: Model = Model() + model: Model = field(default_factory=Model) eom: EOM = None eom_class: Type = EOM From 164c29a1b25c603f388d63a2bd8f5b620fe3a0ec Mon Sep 17 00:00:00 2001 From: crzdg Date: Sat, 15 Apr 2023 09:56:20 +0000 Subject: [PATCH 3/4] Move matplotlib to dev dependencies --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 44e69a5..f5bea81 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,6 @@ readme = "README.rst" python = "^3.9" numpy = "^1.23.5" scipy = "^1.9.3" -matplotlib = "^3.6.2" [tool.poetry.group.dev.dependencies] isort = "^5.10.1" @@ -22,6 +21,7 @@ sphinx-rtd-theme = "^1.1.1" sphinx-autoapi = "^2.0.0" interrogate = "^1.5.0" pydocstyle = "^6.1.1" +matplotlib = "^3.6.2" [build-system] requires = ["poetry-core"] From f85e7501f63b334ebaa1ced3086f443be4014ecc Mon Sep 17 00:00:00 2001 From: crzdg Date: Sat, 15 Apr 2023 09:56:45 +0000 Subject: [PATCH 4/4] Assert for float instead of np.float --- tests/test_eom.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_eom.py b/tests/test_eom.py index ed84c1b..8463958 100644 --- a/tests/test_eom.py +++ b/tests/test_eom.py @@ -35,7 +35,7 @@ def test_compute_forces(self): for f in ["F_lift", "F_drag", "F_grav", "F_total", "Acc"]: assert f in result assert result[f].shape == (3,) - assert result[f].dtype == np.float + assert result[f].dtype == float def test_F_drag_direction(self): eom = EOM(**self.kwargs) @@ -70,14 +70,14 @@ def test_compute_torques_smoke(self): for t in ["T_x_lab", "T_y_lab", "T_x", "T_y", "T_z", "T"]: assert t in result assert result[t].shape == (3,) - assert result[t].dtype == np.float + assert result[t].dtype == float def test_compute_derivatives_smoke(self): eom = EOM(**self.kwargs) coords = np.array([0, 0, 1, 10, 0, 0, 0, 0, 0, 0, 0, 62]) der = eom.compute_derivatives(0, coords) assert der.shape == (12,) - assert der.dtype == np.float + assert der.dtype == float def test_rotation_matrix(self): def trig_functions(phi, theta):