Gilbert Brault há 5 anos atrás
pai
commit
79b479e571

+ 88 - 0
examples/.ipynb_checkpoints/ForwardEuler_comic_strip-checkpoint.py

@@ -0,0 +1,88 @@
+"""Comic strip for illustrating Euler's method for ODEs."""
+
+from pysketcher import *
+import numpy as np
+xkcd = True
+
+xmin = 0
+drawing_tool.set_coordinate_system(xmin=xmin, xmax=4,
+                                   ymin=0, ymax=2.5,
+                                   axis=True, xkcd=xkcd)
+drawing_tool.set_linecolor('blue')
+
+def ForwardEuler(I, a, T, dt):
+    u = [I]
+    t = [0]
+    while t[-1] <= T:
+        u_new = u[-1] - a*dt*u[-1]
+        u.append(u_new)
+        t.append(t[-1] + dt)
+    return np.array(u), np.array(t)
+
+def make_fig(dt=0.5, heading=''):
+    I = 2
+    a = 0.5
+    T_e = 3
+    T_FE = 1
+    t_fine = np.linspace(0, T_e, 101)
+    u_e = I*np.exp(-a*t_fine)
+
+    u, t = ForwardEuler(I, a, T_FE, dt)
+
+    # y = slope*(x - x0) + y0
+    # u_extrapolated = -a*u[-1]*(t - t[-1]) + u[-1]
+    t_future = t[-1] + 1.5   # let the line be longer than one step
+    line = Line((t[-1], u[-1]), (t_future, -a*u[-1]*(t_future - t[-1]) + u[-1]))
+
+    circles = {
+        i: Circle((t[i], u[i]), 0.05).set_linecolor('red').set_filled_curves('red')
+        for i in range(1, len(u))}
+    # Add next predicted point
+    t_next = t[-1] + dt
+    u_next = -a*u[-1]*(t_next - t[-1]) + u[-1]
+    circles[0] = Circle((t_next, u_next), 0.05).\
+                 set_linecolor('red').set_filled_curves('red')
+    circles = Composition(circles)
+
+    curves = Composition(dict(
+        exact=Curve(t_fine, u_e).set_linestyle('dashed'),
+        numerical=Curve(t, u),
+        extrapolation=line.set_linecolor('red').set_linewidth(3)))
+
+    text_exact = Text_wArrow("exact solution", (2.5, 1), (2.5, I*np.exp(-a*2.5)),
+                             alignment='left')
+
+    text_predict = Text_wArrow("Here we know the slope:\n$u'=f(u,t)$!\nLet the solution continue\nalong that slope.",
+                               (1.7, 1.7), (t[-1], u[-1]),
+                               alignment='left')
+    text_next = Text_wArrow("This is the next\npredicted point",
+                            (1, 0.25), (t_next, u_next),
+                            alignment='left')
+
+    text_comment = Text(heading, (0.3, 2.05), alignment='left')
+
+    fig = Composition(dict(curves=curves,
+                           circles=circles,
+                           exact=text_exact,
+                           predict=text_predict,
+                           next=text_next,
+                           comment=text_comment))
+    return fig
+
+fig = make_fig(dt=0.5, heading="Differential equations $u'=f(u,t)$\nare hard to solve,\nbut not with programming!")
+fig.draw()
+drawing_tool.display()
+drawing_tool.savefig('tmp1')
+
+drawing_tool.erase()
+fig = make_fig(dt=0.24, heading='Just reduce the time step\nto make more accurate\npredictions!')
+fig.draw()
+drawing_tool.display()
+drawing_tool.savefig('tmp2')
+
+import os
+comic = 'comic' if xkcd else 'non_comic'
+os.system('doconce combine_images pdf -2 tmp1 tmp2 FE_%s_strip' % comic)
+os.system('doconce combine_images png -2 tmp1 tmp2 FE_%s_strip' % comic)
+
+input()

+ 135 - 0
examples/.ipynb_checkpoints/finite_differences-checkpoint.py

@@ -0,0 +1,135 @@
+"""
+Illustrate forward, backward and centered finite differences
+in four figures.
+"""
+
+from pysketcher import *
+
+#test_test()
+xaxis = 2
+drawing_tool.set_coordinate_system(0, 7, 1, 6, axis=False)
+
+f = SketchyFunc1('$u(t)$')
+x = 3                 # center point where we want the derivative
+xb = 2                # x point used for backward difference
+xf = 4                # x point used for forward difference
+p = (x, f(x))         # center point
+pf = (xf, f(xf))      # forward point
+pb = (xb, f(xb))      # backward point
+r = 0.1               # radius of circles placed at key points
+c = Circle(p, r).set_linecolor('blue')
+cf = Circle(pf, r).set_linecolor('red')
+cb = Circle(pb, r).set_linecolor('green')
+
+# Points in the mesh
+p0 = point(x, xaxis)        # center point
+pf0 = point(xf, xaxis)      # forward point
+pb0 = point(xb, xaxis)      # backward point
+tick = 0.05
+
+# 1D mesh with three points
+mesh = Composition({
+    'tnm1': Text('$t_{n-1}$', pb0 - point(0, 0.3)),
+    'tn': Text('$t_{n}$', p0 - point(0, 0.3)),
+    'tnp1': Text('$t_{n+1}$', pf0 - point(0, 0.3)),
+    'axis': Composition({
+        'hline': Line(pf0-point(3,0), pb0+point(3,0)).\
+        set_linecolor('black').set_linewidth(1),
+        'tick_m1': Line(pf0+point(0,tick), pf0-point(0,tick)).\
+        set_linecolor('black').set_linewidth(1),
+        'tick_n':  Line(p0+point(0,tick), p0-point(0,tick)).\
+        set_linecolor('black').set_linewidth(1),
+        'tick_p1': Line(pb0+point(0,tick), pb0-point(0,tick)).\
+        set_linecolor('black').set_linewidth(1)}),
+    })
+
+# 1D mesh with three points for Crank-Nicolson
+mesh_cn = Composition({
+    'tnm1': Text('$t_{n}$', pb0 - point(0, 0.3)),
+    'tn': Text(r'$t_{n+\frac{1}{2}}$', p0 - point(0, 0.3)),
+    'tnp1': Text('$t_{n+1}$', pf0 - point(0, 0.3)),
+    'axis': Composition({
+        'hline': Line(pf0-point(3,0), pb0+point(3,0)).\
+        set_linecolor('black').set_linewidth(1),
+        'tick_m1': Line(pf0+point(0,tick), pf0-point(0,tick)).\
+        set_linecolor('black').set_linewidth(1),
+        'tick_n':  Line(p0+point(0,tick), p0-point(0,tick)).\
+        set_linecolor('black').set_linewidth(1),
+        'tick_p1': Line(pb0+point(0,tick), pb0-point(0,tick)).\
+        set_linecolor('black').set_linewidth(1)}),
+    })
+
+# Vertical dotted lines at each mesh point
+vlinec = Line(p, p0).set_linestyle('dotted').\
+         set_linecolor('blue').set_linewidth(1)
+vlinef = Line(pf, pf0).set_linestyle('dotted').\
+         set_linecolor('red').set_linewidth(1)
+vlineb = Line(pb, pb0).set_linestyle('dotted').\
+         set_linecolor('green').set_linewidth(1)
+
+# Compose vertical lines for each type of difference
+forward_lines = Composition({'center': vlinec, 'right': vlinef})
+backward_lines = Composition({'center': vlinec, 'left': vlineb})
+centered_lines = Composition({'left': vlineb, 'right': vlinef})
+centered_lines2 = Composition({'left': vlineb, 'right': vlinef,
+                               'center': vlinec})
+
+# Tangents illustrating the derivative
+domain = [1, 5]
+domain2 = [2, 5]
+forward_tangent = Line(p, pf).new_interval(x=domain2).\
+                  set_linestyle('dashed').set_linecolor('red')
+backward_tangent = Line(pb, p).new_interval(x=domain).\
+                   set_linestyle('dashed').set_linecolor('green')
+centered_tangent = Line(pb, pf).new_interval(x=domain).\
+                   set_linestyle('dashed').set_linecolor('blue')
+h = 1E-3  # h in finite difference approx used to compute the exact tangent
+exact_tangent = Line((x+h, f(x+h)), (x-h, f(x-h))).\
+                new_interval(x=domain).\
+                set_linestyle('dotted').set_linecolor('black')
+
+forward = Composition(
+    dict(tangent=forward_tangent,
+         point1=c, point2=cf, coor=forward_lines,
+         name=Text('forward',
+                   forward_tangent.geometric_features()['end'] + \
+                   point(0.1,0), alignment='left')))
+backward = Composition(
+    dict(tangent=backward_tangent,
+         point1=c, point2=cb, coor=backward_lines,
+         name=Text('backward',
+                   backward_tangent.geometric_features()['end'] + \
+                   point(0.1,0), alignment='left')))
+centered = Composition(
+    dict(tangent=centered_tangent,
+         point1=cb, point2=cf, point=c, coor=centered_lines2,
+         name=Text('centered',
+                   centered_tangent.geometric_features()['end'] + \
+                   point(0.1,0), alignment='left')))
+
+exact = Composition(dict(graph=f, tangent=exact_tangent))
+forward = Composition(dict(difference=forward, exact=exact)).\
+          set_name('forward')
+backward = Composition(dict(difference=backward, exact=exact)).\
+           set_name('backward')
+centered = Composition(dict(difference=centered, exact=exact)).\
+           set_name('centered')
+all = Composition(
+    dict(exact=exact, forward=forward, backward=backward,
+         centered=centered)).set_name('all')
+
+for fig in forward, backward, centered, all:
+    drawing_tool.erase()
+    fig.draw()
+    mesh.draw()
+    drawing_tool.display()
+    drawing_tool.savefig('fd_'+fig.get_name())
+# Crank-Nicolson around t_n+1/2
+drawing_tool.erase()
+centered.draw()
+mesh_cn.draw()
+drawing_tool.display()
+drawing_tool.savefig('fd_centered_CN')
+
+input()
+

+ 74 - 92
notebooks/.ipynb_checkpoints/wheelonInclinedPlane-checkpoint.ipynb

@@ -22,7 +22,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "from ipywidgets import FloatSlider"
+    "from ipywidgets import FloatSlider, AppLayout, Label, HBox"
    ]
   },
   {
@@ -40,8 +40,42 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "from pysketcher import *\n",
-    "\n",
+    "import time"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from IPython.display import display, clear_output"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from pysketcher import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "g = 9.81"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
     "def inclined_plane():\n",
     "    theta = 30.\n",
     "    L = 10.\n",
@@ -94,8 +128,6 @@
     "\n",
     "    drawing_tool.set_linecolor('black')\n",
     "    N = Force(contact - 2*r*normal_vec, contact, r'$N$', text_pos='start')\n",
-    "    V = Force(c, c + 0.001*tangent_vec, r'$V$', text_pos='end')\n",
-    "    V.set_linecolor('red')\n",
     "    mg = Gravity(c, 3*r, text='$Mg$')\n",
     "\n",
     "    x_const = Line(contact, contact + point(0,4))\n",
@@ -107,7 +139,7 @@
     "\n",
     "    body  = Composition({'wheel': wheel, 'N': N, 'mg': mg})\n",
     "    fixed = Composition({'angle': angle, 'inclined wall': wall,\n",
-    "                         'wheel': wheel, 'V': V, 'ground': ground,\n",
+    "                         'ground': ground,\n",
     "                         'x start': x_const, 'x axis': x_axis})\n",
     "\n",
     "    fig = Composition({'body': body, 'fixed elements': fixed})\n",
@@ -117,31 +149,36 @@
     "def position(t):\n",
     "    \"\"\"Position of center point of wheel.\"\"\"\n",
     "    global tangent_vec,c\n",
-    "    return c + 7*t**2*tangent_vec\n",
-    "\n",
-    "def speed(t):\n",
-    "    global tangent_vec\n",
-    "    return 0.14*t*tangent_vec    \n",
+    "    return c + 0.5*g*t**2*tangent_vec\n",
     "\n",
     "t = 0\n",
     "\n",
+    "def speed(displacement,dt):\n",
+    "    if dt != 0: \n",
+    "        v = (displacement)/dt\n",
+    "        #print(v)\n",
+    "        v = numpy.sqrt(v[0]**2 + v[1]**2)\n",
+    "    else:\n",
+    "        v = 0\n",
+    "    return v\n",
+    "        \n",
     "def move(change):\n",
-    "    global fig,t\n",
+    "    global fig,t,label,x,x0,dt\n",
     "    dt = change.new - t \n",
     "    t = change.new\n",
     "    drawing_tool.erase()\n",
     "    x = position(t)\n",
     "    x0 = position(t-dt)\n",
-    "    displacement = x - x0\n",
-    "    fig['fixed elements']['V']['arrow']['line'] = Line(x,x+speed(t))\n",
+    "    displacement = x - x0    \n",
     "    fig['body'].translate(displacement)\n",
     "    fig.draw()\n",
-    "    drawing_tool.display()"
+    "    label.value = f\"v={speed(displacement,dt):.2f}\"\n",
+    "    #drawing_tool.display()"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 9,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -158,42 +195,27 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 10,
    "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "application/vnd.jupyter.widget-view+json": {
-       "model_id": "1af7c7deda7b418a8a170ec0b34505ec",
-       "version_major": 2,
-       "version_minor": 0
-      },
-      "text/plain": [
-       "FloatSlider(value=0.0, description='Time:', max=1.0, step=0.03333333333333333)"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    }
-   ],
+   "outputs": [],
    "source": [
-    "slider"
+    "label = Label(value=\"0\")"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 11,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "da53e1cea5d447b5af22e27766617152",
+       "model_id": "d62ee3eb721b4dfb8e5ed6cb5f0b506b",
        "version_major": 2,
        "version_minor": 0
       },
       "text/plain": [
-       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
+       "AppLayout(children=(HBox(children=(FloatSlider(value=0.0, description='Time:', max=1.0, step=0.033333333333333…"
       ]
      },
      "metadata": {},
@@ -201,65 +223,22 @@
     }
    ],
    "source": [
-    "fig,normal_vec,tangent_vec,c = inclined_plane()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "speed(0)"
+    "fig,normal_vec,tangent_vec,c = inclined_plane()\n",
+    "AppLayout(\n",
+    "    center=drawing_tool.mpl.gcf().canvas,\n",
+    "    footer=HBox([slider,label]),\n",
+    "    pane_heights=[0, 6, 1]\n",
+    ")\n",
+    "#drawing_tool.mpl.ion()"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 12,
    "metadata": {},
    "outputs": [],
    "source": [
-    "position(0)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 8,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "array([4.5       , 4.90747729])"
-      ]
-     },
-     "execution_count": 8,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "fig['fixed elements']['V']['arrow']['line'].x"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "array([4.5       , 4.90747729])"
-      ]
-     },
-     "execution_count": 9,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "fig['fixed elements']['V']['arrow']['line'].y"
+    "drawing_tool.mpl.ion()"
    ]
   },
   {
@@ -268,7 +247,10 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "speed(0.3)"
+    "for t in numpy.linspace(0.0,1.0,100):\n",
+    "    slider.value = t\n",
+    "    print(t)\n",
+    "    clear_output(wait=True)"
    ]
   },
   {
@@ -277,7 +259,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "t"
+    "drawing_tool.mpl.ioff()"
    ]
   },
   {
@@ -286,7 +268,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "position(t)"
+    "fig"
    ]
   },
   {

+ 121 - 72
notebooks/wheelonInclinedPlane.ipynb

@@ -22,7 +22,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "from ipywidgets import FloatSlider"
+    "from ipywidgets import FloatSlider, AppLayout, Label, HBox"
    ]
   },
   {
@@ -40,8 +40,42 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "from pysketcher import *\n",
-    "\n",
+    "import time"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from IPython.display import display, clear_output"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from pysketcher import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "g = 9.81"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
     "def inclined_plane():\n",
     "    theta = 30.\n",
     "    L = 10.\n",
@@ -94,8 +128,6 @@
     "\n",
     "    drawing_tool.set_linecolor('black')\n",
     "    N = Force(contact - 2*r*normal_vec, contact, r'$N$', text_pos='start')\n",
-    "    V = Force(c, c + 0.001*tangent_vec, r'$V$', text_pos='end')\n",
-    "    V.set_linecolor('red')\n",
     "    mg = Gravity(c, 3*r, text='$Mg$')\n",
     "\n",
     "    x_const = Line(contact, contact + point(0,4))\n",
@@ -107,7 +139,7 @@
     "\n",
     "    body  = Composition({'wheel': wheel, 'N': N, 'mg': mg})\n",
     "    fixed = Composition({'angle': angle, 'inclined wall': wall,\n",
-    "                         'wheel': wheel, 'V': V, 'ground': ground,\n",
+    "                         'ground': ground,\n",
     "                         'x start': x_const, 'x axis': x_axis})\n",
     "\n",
     "    fig = Composition({'body': body, 'fixed elements': fixed})\n",
@@ -117,31 +149,36 @@
     "def position(t):\n",
     "    \"\"\"Position of center point of wheel.\"\"\"\n",
     "    global tangent_vec,c\n",
-    "    return c + 7*t**2*tangent_vec\n",
-    "\n",
-    "def speed(t):\n",
-    "    global tangent_vec\n",
-    "    return 0.14*t*tangent_vec    \n",
+    "    return c + 0.5*g*t**2*tangent_vec\n",
     "\n",
     "t = 0\n",
     "\n",
+    "def speed(displacement,dt):\n",
+    "    if dt != 0: \n",
+    "        v = (displacement)/dt\n",
+    "        #print(v)\n",
+    "        v = numpy.sqrt(v[0]**2 + v[1]**2)\n",
+    "    else:\n",
+    "        v = 0\n",
+    "    return v\n",
+    "        \n",
     "def move(change):\n",
-    "    global fig,t\n",
+    "    global fig,t,label,x,x0,dt\n",
     "    dt = change.new - t \n",
     "    t = change.new\n",
     "    drawing_tool.erase()\n",
     "    x = position(t)\n",
     "    x0 = position(t-dt)\n",
-    "    displacement = x - x0\n",
-    "    fig['fixed elements']['V']['arrow']['line'] = Line(x,x+speed(t))\n",
+    "    displacement = x - x0    \n",
     "    fig['body'].translate(displacement)\n",
     "    fig.draw()\n",
-    "    drawing_tool.display()"
+    "    label.value = f\"v={speed(displacement,dt):.2f}\"\n",
+    "    #drawing_tool.display()"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 9,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -158,42 +195,27 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 10,
    "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "application/vnd.jupyter.widget-view+json": {
-       "model_id": "4c6c086038e241819081cf84d58d0331",
-       "version_major": 2,
-       "version_minor": 0
-      },
-      "text/plain": [
-       "FloatSlider(value=0.0, description='Time:', max=1.0, step=0.03333333333333333)"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    }
-   ],
+   "outputs": [],
    "source": [
-    "slider"
+    "label = Label(value=\"0\")"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 11,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "1b7605e135de4e258d920e8c0da91831",
+       "model_id": "d62ee3eb721b4dfb8e5ed6cb5f0b506b",
        "version_major": 2,
        "version_minor": 0
       },
       "text/plain": [
-       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
+       "AppLayout(children=(HBox(children=(FloatSlider(value=0.0, description='Time:', max=1.0, step=0.033333333333333…"
       ]
      },
      "metadata": {},
@@ -201,43 +223,22 @@
     }
    ],
    "source": [
-    "fig,normal_vec,tangent_vec,c = inclined_plane()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "speed(0)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "position(0)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "fig['fixed elements']['V']['arrow']['line'].x"
+    "fig,normal_vec,tangent_vec,c = inclined_plane()\n",
+    "AppLayout(\n",
+    "    center=drawing_tool.mpl.gcf().canvas,\n",
+    "    footer=HBox([slider,label]),\n",
+    "    pane_heights=[0, 6, 1]\n",
+    ")\n",
+    "#drawing_tool.mpl.ion()"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 12,
    "metadata": {},
    "outputs": [],
    "source": [
-    "fig['fixed elements']['V']['arrow']['line'].y"
+    "drawing_tool.mpl.ion()"
    ]
   },
   {
@@ -246,7 +247,10 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "speed(0.3)"
+    "for t in numpy.linspace(0.0,1.0,100):\n",
+    "    slider.value = t\n",
+    "    print(t)\n",
+    "    clear_output(wait=True)"
    ]
   },
   {
@@ -255,16 +259,61 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "t"
+    "drawing_tool.mpl.ioff()"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 14,
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<bound method Shape.show_hierarchy of {\n",
+       "'body': {\n",
+       "    'wheel': {\n",
+       "        'outer': {\n",
+       "            'arc': \"181 (x,y) coords linecolor='b' fillcolor='b' fillpattern=''\",},\n",
+       "        'inner': {\n",
+       "            'arc': \"181 (x,y) coords linecolor='b' fillcolor='w' fillpattern=''\",},},\n",
+       "    'N': {\n",
+       "        'arrow': {\n",
+       "            'line': \"2 (x,y) coords arrow='->'\",},\n",
+       "        'text': \"Text at (2.7875,1.94134)\",},\n",
+       "    'mg': {\n",
+       "        'arrow': {\n",
+       "            'line': \"2 (x,y) coords linecolor='k' arrow='->'\",},\n",
+       "        'text': \"Text at (4.5,1.48248)\",},},\n",
+       "'fixed elements': {\n",
+       "    'angle': {\n",
+       "        'arc': {\n",
+       "            'arc': \"181 (x,y) coords linecolor='k' linewidth=1\",},\n",
+       "        'text': \"Text at (7.86074,0.841162)\",},\n",
+       "    'inclined wall': {\n",
+       "        'wall': \"4 (x,y) coords fillcolor='white' fillpattern='/'\",},\n",
+       "    'ground': {\n",
+       "        'line': \"2 (x,y) coords linecolor='k' linewidth=1 linestyle='dashed'\",},\n",
+       "    'x start': {\n",
+       "        'line': \"2 (x,y) coords linestyle='dotted'\",},\n",
+       "    'x axis': {\n",
+       "        'arrow': {\n",
+       "            'line': {\n",
+       "                'line': \"2 (x,y) coords\",},\n",
+       "            'head left': {\n",
+       "                'line': \"2 (x,y) coords linestyle='solid'\",},\n",
+       "            'head right': {\n",
+       "                'line': \"2 (x,y) coords linestyle='solid'\",},},\n",
+       "        'label': \"Text at (9.25278,4.47286)\",},},}>"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
    "source": [
-    "position(t)"
+    "fig.show_hierarchy"
    ]
   },
   {

+ 1 - 1
pysketcher/MatplotlibDraw.py

@@ -116,7 +116,7 @@ class MatplotlibDraw(object):
         else:
             self.instruction_file = None
 
-        self.mpl.ion()  # important for interactive drawing and animation
+        self.mpl.ioff()  # important for interactive drawing and animation
         if self.instruction_file:
             self.instruction_file.write("""\
 import matplotlib