Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
| Download
"Guiding Future STEM Leaders through Innovative Research Training" ~ thinkingbeyond.education
Project: stephanie's main branch
Path: ThinkingBeyond Activities / BeyondAI-2024-Mentee-Projects / shaana-karuna / Continuity_Video_Final.ipynb~2
Views: 1176Image: ubuntu2204
{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "provenance": [], "authorship_tag": "ABX9TyMie/9tJVpOnaI2FhwUvsTH", "include_colab_link": true }, "kernelspec": { "name": "python3", "display_name": "Python 3" }, "language_info": { "name": "python" } }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "view-in-github", "colab_type": "text" }, "source": [ "<a href=\"https://colab.research.google.com/github/ThinkingBeyond/BeyondAI-2024/blob/main/shaana-karuna/Continuity_Video_Final.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" ] }, { "cell_type": "markdown", "source": [ "#Summary of code\n", "\n", "This code creates a video explaining the epsilon-delta definition of continuity. It is divided into 2 parts." ], "metadata": { "id": "JEyIrK1HZxNe" } }, { "cell_type": "markdown", "source": [ "#Setting up Manim\n" ], "metadata": { "id": "Uxfsc247Z94w" } }, { "cell_type": "markdown", "source": [ "This section installs Manim and IPython." ], "metadata": { "id": "x51Xk38NeE6u" } }, { "cell_type": "code", "source": [ "!sudo apt update\n", "!sudo apt install libcairo2-dev ffmpeg \\\n", " texlive texlive-latex-extra texlive-fonts-extra \\\n", " texlive-latex-recommended texlive-science \\\n", " tipa libpango1.0-dev\n", "!pip install manim==0.18.1\n", "!pip install IPython==8.21.0" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "rqUI4fVf5vPD", "outputId": "7cd772be-17ab-488e-894e-c0589f4e7156", "collapsed": true }, "execution_count": 2, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "\u001b[33m\r0% [Working]\u001b[0m\r \rHit:1 https://cloud.r-project.org/bin/linux/ubuntu jammy-cran40/ InRelease\n", "\u001b[33m\r0% [Connecting to archive.ubuntu.com (185.125.190.82)] [Connecting to security.\u001b[0m\r \rHit:2 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64 InRelease\n", "\u001b[33m\r0% [Connecting to archive.ubuntu.com (185.125.190.82)] [Waiting for headers] [C\u001b[0m\r \rHit:3 http://security.ubuntu.com/ubuntu jammy-security InRelease\n", "Hit:4 http://archive.ubuntu.com/ubuntu jammy InRelease\n", "Hit:5 https://r2u.stat.illinois.edu/ubuntu jammy InRelease\n", "Hit:6 http://archive.ubuntu.com/ubuntu jammy-updates InRelease\n", "Hit:7 http://archive.ubuntu.com/ubuntu jammy-backports InRelease\n", "Hit:8 https://ppa.launchpadcontent.net/deadsnakes/ppa/ubuntu jammy InRelease\n", "Hit:9 https://ppa.launchpadcontent.net/graphics-drivers/ppa/ubuntu jammy InRelease\n", "0% [Waiting for headers]\u001b[0m^C\n", "Reading package lists... Done\n", "Building dependency tree... Done\n", "Reading state information... Done\n", "libcairo2-dev is already the newest version (1.16.0-5ubuntu2).\n", "texlive is already the newest version (2021.20220204-1).\n", "texlive-fonts-extra is already the newest version (2021.20220204-1).\n", "texlive-latex-extra is already the newest version (2021.20220204-1).\n", "texlive-latex-recommended is already the newest version (2021.20220204-1).\n", "texlive-science is already the newest version (2021.20220204-1).\n", "tipa is already the newest version (2:1.3-21).\n", "libpango1.0-dev is already the newest version (1.50.6+ds-2ubuntu1).\n", "ffmpeg is already the newest version (7:4.4.2-0ubuntu0.22.04.1).\n", "0 upgraded, 0 newly installed, 0 to remove and 51 not upgraded.\n", "Requirement already satisfied: manim==0.18.1 in /usr/local/lib/python3.10/dist-packages (0.18.1)\n", "Requirement already satisfied: Pillow>=9.1 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (11.0.0)\n", "Requirement already satisfied: Pygments>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (2.18.0)\n", "Requirement already satisfied: click>=8.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (8.1.7)\n", "Requirement already satisfied: cloup>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (3.0.5)\n", "Requirement already satisfied: decorator>=4.3.2 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (4.4.2)\n", "Requirement already satisfied: isosurfaces>=0.1.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (0.1.2)\n", "Requirement already satisfied: manimpango<1.0.0,>=0.5.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (0.6.0)\n", "Requirement already satisfied: mapbox-earcut>=1.0.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (1.0.2)\n", "Requirement already satisfied: moderngl<6.0.0,>=5.0.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (5.12.0)\n", "Requirement already satisfied: moderngl-window>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (3.0.3)\n", "Requirement already satisfied: networkx>=2.6 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (3.4.2)\n", "Requirement already satisfied: numpy>=1.26 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (1.26.4)\n", "Requirement already satisfied: pycairo<2.0.0,>=1.13 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (1.27.0)\n", "Requirement already satisfied: pydub>=0.20.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (0.25.1)\n", "Requirement already satisfied: rich>=12.0.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (13.9.4)\n", "Requirement already satisfied: scipy>=1.6.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (1.13.1)\n", "Requirement already satisfied: screeninfo>=0.7 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (0.8.1)\n", "Requirement already satisfied: skia-pathops>=0.7.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (0.8.0.post2)\n", "Requirement already satisfied: srt>=3.0.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (3.5.3)\n", "Requirement already satisfied: svgelements>=1.8.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (1.9.6)\n", "Requirement already satisfied: tqdm>=4.0.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (4.66.6)\n", "Requirement already satisfied: typing-extensions>=4.0.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (4.12.2)\n", "Requirement already satisfied: watchdog>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from manim==0.18.1) (6.0.0)\n", "Requirement already satisfied: glcontext>=3.0.0 in /usr/local/lib/python3.10/dist-packages (from moderngl<6.0.0,>=5.0.0->manim==0.18.1) (3.0.0)\n", "Requirement already satisfied: pyglet>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from moderngl-window>=2.0.0->manim==0.18.1) (2.0.20)\n", "Requirement already satisfied: pyglm<3,>=2.7.0 in /usr/local/lib/python3.10/dist-packages (from moderngl-window>=2.0.0->manim==0.18.1) (2.7.3)\n", "Requirement already satisfied: markdown-it-py>=2.2.0 in /usr/local/lib/python3.10/dist-packages (from rich>=12.0.0->manim==0.18.1) (3.0.0)\n", "Requirement already satisfied: mdurl~=0.1 in /usr/local/lib/python3.10/dist-packages (from markdown-it-py>=2.2.0->rich>=12.0.0->manim==0.18.1) (0.1.2)\n", "Requirement already satisfied: IPython==8.21.0 in /usr/local/lib/python3.10/dist-packages (8.21.0)\n", "Requirement already satisfied: decorator in /usr/local/lib/python3.10/dist-packages (from IPython==8.21.0) (4.4.2)\n", "Requirement already satisfied: jedi>=0.16 in /usr/local/lib/python3.10/dist-packages (from IPython==8.21.0) (0.19.2)\n", "Requirement already satisfied: matplotlib-inline in /usr/local/lib/python3.10/dist-packages (from IPython==8.21.0) (0.1.7)\n", "Requirement already satisfied: prompt-toolkit<3.1.0,>=3.0.41 in /usr/local/lib/python3.10/dist-packages (from IPython==8.21.0) (3.0.48)\n", "Requirement already satisfied: pygments>=2.4.0 in /usr/local/lib/python3.10/dist-packages (from IPython==8.21.0) (2.18.0)\n", "Requirement already satisfied: stack-data in /usr/local/lib/python3.10/dist-packages (from IPython==8.21.0) (0.6.3)\n", "Requirement already satisfied: traitlets>=5 in /usr/local/lib/python3.10/dist-packages (from IPython==8.21.0) (5.7.1)\n", "Requirement already satisfied: exceptiongroup in /usr/local/lib/python3.10/dist-packages (from IPython==8.21.0) (1.2.2)\n", "Requirement already satisfied: pexpect>4.3 in /usr/local/lib/python3.10/dist-packages (from IPython==8.21.0) (4.9.0)\n", "Requirement already satisfied: parso<0.9.0,>=0.8.4 in /usr/local/lib/python3.10/dist-packages (from jedi>=0.16->IPython==8.21.0) (0.8.4)\n", "Requirement already satisfied: ptyprocess>=0.5 in /usr/local/lib/python3.10/dist-packages (from pexpect>4.3->IPython==8.21.0) (0.7.0)\n", "Requirement already satisfied: wcwidth in /usr/local/lib/python3.10/dist-packages (from prompt-toolkit<3.1.0,>=3.0.41->IPython==8.21.0) (0.2.13)\n", "Requirement already satisfied: executing>=1.2.0 in /usr/local/lib/python3.10/dist-packages (from stack-data->IPython==8.21.0) (2.1.0)\n", "Requirement already satisfied: asttokens>=2.1.0 in /usr/local/lib/python3.10/dist-packages (from stack-data->IPython==8.21.0) (3.0.0)\n", "Requirement already satisfied: pure-eval in /usr/local/lib/python3.10/dist-packages (from stack-data->IPython==8.21.0) (0.2.3)\n" ] } ] }, { "cell_type": "code", "source": [ "from manim import *" ], "metadata": { "id": "QXeDXoIW5z2g" }, "execution_count": 1, "outputs": [] }, { "cell_type": "markdown", "source": [ "#Setting up colours" ], "metadata": { "id": "9eQlgBLMaAuy" } }, { "cell_type": "markdown", "source": [ "This section uses specific hex codes to define colours to be used later." ], "metadata": { "id": "Lxg3kDxUhK1b" } }, { "cell_type": "code", "source": [ "GREENISHWHITE = ManimColor.from_hex(\"#e6ebd5\")\n", "NEWGREEN = ManimColor.from_hex(\"#93c280\")\n", "NEWDARKGREEN = ManimColor.from_hex(\"#17282a\")\n", "NEWMEDIUMGREEN = ManimColor.from_hex(\"#0a5936\")" ], "metadata": { "id": "GRjN8R2GDa2o" }, "execution_count": 5, "outputs": [] }, { "cell_type": "markdown", "source": [ "#Part 1\n", "\n", "The first part of the video introduces the concept of a continuous function as a 'function you can draw without lifting your pen off the page'. It uses an animation of a straight line bending into different continuous functions to illustrate this idea.\n", "\n", "Then, it adds more formality to this concept by introducing the idea that as 2 inputs approach each other, so should the outputs at these 2 points." ], "metadata": { "id": "b7D-jBggaFo5" } }, { "cell_type": "code", "source": [ "class Continuity(Scene):\n", " def construct(self):\n", "\n", "#Set the background colour.\n", " self.camera.background_color = NEWDARKGREEN\n", "\n", "#Define the axes and set the colour of the axes.\n", " axes = Axes(\n", " x_range=[-5, 6, 1],\n", " y_range=[-3, 3, 1],\n", " axis_config={\"color\": GREENISHWHITE}\n", " )\n", "\n", "#Add numbers to the axes.\n", " numbered_axes = axes.add_coordinates()\n", "\n", "#Define a straight line on the axes.\n", " line = axes.plot_line_graph(\n", " x_values=[-5, 5],\n", " y_values=[1, 1],\n", " add_vertex_dots=False,\n", " line_color=NEWGREEN,\n", " )\n", "\n", "#Define a quadratic on the axes, with the same start and end points as the line for smooth transformation.\n", " quadratic = axes.plot(\n", " lambda x: (x**2 - 25)/12+1,\n", " x_range=[-5, 5],\n", " color=NEWGREEN\n", " )\n", "\n", "#Define a sine curve on the axes, with the same start and end points as the line for smooth transformation.\n", " sin = axes.plot(\n", " lambda x: np.sin(5*x/6),\n", " x_range=[-5, 5],\n", " color=NEWGREEN\n", " )\n", "\n", "#Define cubic on the axes, with the same start and end points as the line for smooth transformation.\n", " cubic = axes.plot(\n", " lambda x: x*(x-5)*(x+5)/35+1,\n", " x_range=[-5, 5],\n", " color=NEWGREEN\n", " )\n", "\n", "#Define and position the point y.\n", " point_coords = (-1.5, 1.975)\n", " point_location = axes.coords_to_point(*point_coords)\n", " y = Dot(point_location, color=NEWMEDIUMGREEN)\n", "\n", "#Define and position text describing a continuous function.\n", " text = Tex(\"A continuous function is often described as 'a function that you can draw without lifting your pen off the page'.\", font_size=20)\n", " text.move_to([0,3.5,0])\n", "\n", "##Sets up a variable tracking the position of x (dot) and a function used to update its position.\n", "#The starting position of dot is at x = -3.\n", " x_tracker = ValueTracker(-3)\n", "\n", "#Defines a function for updating the position of dot. Updates the position depending on the tracking variable x_tracker and the y value at this point.\n", " def update_dot(dot):\n", " x1 = x_tracker.get_value()\n", " y1 = x1*(x1-5)*(x1+5)/35+1\n", " dot.move_to(axes.coords_to_point(x1, y1))\n", "\n", "#Defines dot (x) and assignes it the previously defined update function update_dot.\n", "\n", " dot = Dot(color=GREENISHWHITE)\n", " dot.add_updater(update_dot)\n", "\n", "##Sets up a variable tracking the position of x2 (dot2) and a function used to update its position.\n", "#The starting position of dot2 is at x = -0.9.\n", " x2_tracker = ValueTracker(-0.9)\n", "\n", "#Defines a function for updating the position of dot2. Updates the position depending on the tracking variable x2_tracker and the y value at this point.\n", " def update_dot2(dot2):\n", " x2 = x2_tracker.get_value()\n", " y2 = x2*(x2-5)*(x2+5)/35+1\n", " dot2.move_to(axes.coords_to_point(x2, y2))\n", "\n", "#Defines dot2 (x2) and assignes it the previously defined update function update_dot2.\n", " dot2 = Dot(color=GREENISHWHITE)\n", " dot2.add_updater(update_dot2)\n", "\n", "#Defines fx, a horizontal line through dot to illustrate the output at x approaching the output at y. This line is always drawn at the y value of dot.\n", " fx = always_redraw(lambda: DashedLine(\n", " start=axes.c2p(-5, dot.get_y()),\n", " end=axes.c2p(5, dot.get_y()),\n", " color=GREENISHWHITE,\n", " ))\n", "\n", "#Defines fx, a horizontal line through dot to illustrate the output at x2 approaching the output at y. This line is always drawn at the y value of dot2.\n", " fx2 = always_redraw(lambda: DashedLine(\n", " start=axes.c2p(-5, dot2.get_y()),\n", " end=axes.c2p(5, dot2.get_y()),\n", " color=GREENISHWHITE,\n", " ))\n", "\n", "#Defines fy, a horizontal line through dot to illustrate the output at y.\n", " fy = DashedLine(start=axes.c2p(-5, 1.975),\n", " end=axes.c2p(5, 1.975),\n", " color=GREEN)\n", "\n", "## Start the animation\n", "\n", "#Writes 'A continuous function is often described as 'a function that you can draw without lifting your pen off the page'.', then waits 1 second.\n", " self.play(Write(text))\n", " self.wait(1)\n", "\n", "#Adds the axes and line. Then transforms the line to the quadratic, then the sine curve, then the cubic, then fades out the text.\n", " self.play(Create(numbered_axes))\n", " self.play(Create(line))\n", " self.play(Transform(line, quadratic))\n", " self.play(Transform(line, sin))\n", " self.play(Transform(line, cubic))\n", " self.play(FadeOut(text))\n", "\n", "#Changes the text, then writes it and waits 1 second.\n", " text = Tex(\"But how can we define a continuous function more precisely?\", font_size=20)\n", " text.move_to([0,3.5,0])\n", " self.play(Write(text))\n", " self.wait(1)\n", "\n", "#Fades out the text, changes it then writes it, adds y to the scene then waits 1 second.\n", " self.play(FadeOut(text))\n", " text = Tex(\"Consider a fixed point on the function, $(y, f(y))$.\",font_size=20)\n", " text.move_to([0,3.5,0])\n", " self.play(Write(text))\n", " self.wait(0.5)\n", " self.play(Create(y))\n", " self.wait(1)\n", "\n", "#Fades out the text, changes it then writes it, adds x to the scene and waits 1 second.\n", " self.play(FadeOut(text))\n", " text = Tex(\"Now consider another variable point on the function, $(x,f(x))$.\",font_size=20)\n", " text.move_to([0,3.5,0])\n", " self.play(Write(text))\n", " self.wait(0.5)\n", " dot.move_to(axes.coords_to_point(-3, 2.37))\n", " self.add(dot)\n", " self.wait(1)\n", "\n", "#Fades out the text, changes the text and rewrites it.\n", "#Adds fx and fy to the scene and animates x to approach y (and therefore fx to approach fy) using x_tracker, and waits 2 seconds.\n", " self.play(FadeOut(text))\n", " text = Tex(\"The function is continuous at the point $y$, if as x approaches y, f(x) approaches $f(y)$.\",font_size=20)\n", " text.move_to([0,3.5,0])\n", " self.play(Write(text))\n", " self.add(fy,fx)\n", " self.play(x_tracker.animate.set_value(-1.5), run_time=3, rate_func=linear)\n", " self.wait(2)\n", "\n", "#Fades out the text, dot (x) and fx, replaces the text and rewrites it.\n", "#Resets the value of x_tracker and adds dot and fx back.\n", "#Also adds dot2 (x2) and fx2.\n", "#Animates dot and dot2 to approach y.\n", "#Waits 2 seconds, then fades out text then removes fx, fx2, dot and dot2.\n", "\n", " self.play(FadeOut(text, dot, fx))\n", " text = Tex(\"This has to work on both sides of $y$.\",font_size=20)\n", " text.move_to([0,3.5,0])\n", " self.play(Write(text))\n", " x_tracker = ValueTracker(-3)\n", " self.add(dot, dot2, fx, fx2)\n", " self.play(x_tracker.animate.set_value(-1.5), x2_tracker.animate.set_value(-1.5), run_time=3, rate_func=linear)\n", " self.wait(2)\n", " self.play(FadeOut(text))\n", " self.remove(fx, fx2, dot, dot2)\n", " self.wait()\n", "\n" ], "metadata": { "id": "rsq3mb8xbwi-" }, "execution_count": 12, "outputs": [] }, { "cell_type": "markdown", "source": [ "Finally, the following command is used to render the scene and save it in the subfolder 'jupyter' in the folder 'media'.\n" ], "metadata": { "id": "4sD46Q5Vhyjq" } }, { "cell_type": "code", "source": [ "%%manim -qm -v WARNING Continuity" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 204 }, "id": "UUND1SyWhnJK", "outputId": "cf48ae9c-725f-4fc7-8af3-dcd2f332d4ad" }, "execution_count": 13, "outputs": [ { "output_type": "display_data", "data": { "text/plain": [ "Manim Community \u001b[32mv0.\u001b[0m\u001b[32m18.1\u001b[0m\n", "\n" ], "text/html": [ "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">Manim Community <span style=\"color: #008000; text-decoration-color: #008000\">v0.18.1</span>\n", "\n", "</pre>\n" ] }, "metadata": {} }, { "output_type": "stream", "name": "stderr", "text": [] }, { "output_type": "display_data", "data": { "text/plain": [ "<IPython.core.display.Video object>" ], "text/html": [ "<video src=\"media/jupyter/Continuity@2024-12-18@16-44-26.mp4\" controls autoplay loop style=\"max-width: 60%;\" >\n", " Your browser does not support the <code>video</code> element.\n", " </video>" ] }, "metadata": {} } ] }, { "cell_type": "markdown", "source": [ "#Part 2\n", "\n", "The second and final part of the animation links what has been previously shown to the formal definition of continuity, and applies this definition to another example." ], "metadata": { "id": "hTrqa6GoaSV5" } }, { "cell_type": "code", "source": [ "class Continuity2(Scene):\n", " def construct(self):\n", "\n", "#Set the background colour.\n", " self.camera.background_color = NEWDARKGREEN\n", " axes = Axes(\n", " x_range=[-5, 6, 1],\n", " y_range=[-3, 3, 1],\n", " axis_config={\"color\": GREENISHWHITE}\n", " )\n", "\n", "#Add numbers to the axes.\n", " numbered_axes = axes.add_coordinates()\n", "\n", "#Define a cubic on the axes.\n", " cubic = axes.plot(\n", " lambda x: x*(x-5)*(x+5)/35+1,\n", " x_range=[-5, 5],\n", " color=NEWGREEN\n", " )\n", "\n", "#Define a sine curve on the axes.\n", " sin = axes.plot(\n", " lambda x: np.sin(5*x/6),\n", " x_range=[-5, 5],\n", " color=NEWGREEN\n", " )\n", "\n", "#Define and position text.\n", " text = Tex(\"We have now seen that if we want $|f(x)-f(y)|<\\epsilon$ for at a point $y$, we can find a $\\delta$ such that if $|x-y|<\\delta$ then this is true.\", font_size=20)\n", " text.move_to([0,3.5,0])\n", "\n", "#Defines fy, a horizontal line through dot to illustrate the output at y.\n", " fy = DashedLine(start=axes.c2p(-5, 1.975),\n", " end=axes.c2p(5, 1.975),\n", " color=GREEN)\n", "\n", "#Defines fx1, a horizontal line.\n", " fx1 = DashedLine(start=axes.c2p(-5, 2.25),\n", " end=axes.c2p(5, 2.25),\n", " color=GREENISHWHITE)\n", "\n", "#Defines fx2, a horizontal line. fx2 and fx1 are equidistant from fy and are on the opposite sides of fy.\n", " fx2 = DashedLine(start=axes.c2p(-5, 1.75),\n", " end=axes.c2p(5, 1.75),\n", " color=GREENISHWHITE)\n", "\n", "#Defines y.\n", " point_coords = (-1.5, 1.975)\n", " point_location = axes.coords_to_point(*point_coords)\n", " y = Dot(point_location, color=NEWMEDIUMGREEN)\n", "\n", "## Animation starts here\n", "#Axes, the cubic, y and dy are added to the scene. Creates fx1 and fx2 and then writes the text, then waits 2 seconds.\n", " self.add(axes, cubic, y, fy)\n", " self.play(Create(fx1))\n", " self.play(Create(fx2))\n", " self.play(Write(text))\n", " self.wait(2)\n", "\n", "#Fades out the text then changes and rewrites it. Waits 0.5 seconds, then fades fx1, fx2, y and fy, waits 0.1 seconds then transforms the cubic into a sin curve.\n", " self.play(FadeOut(text))\n", " text = Tex(\"This is the epsilon-delta definition of a continuous function, as used in our proof. Let's look at another function to see that this definition works.\", font_size=20)\n", " text.move_to([0,3.5,0])\n", " self.play(Write(text))\n", " self.wait(0.5)\n", " self.play(FadeOut(fx1, fx2, y, fy))\n", " self.wait(0.1)\n", " self.play(Transform(cubic, sin))\n", "\n", "\n", "#Redefines fx1 and fx2 to change their positions.\n", " fx1 = DashedLine(start=axes.c2p(-5, 0.75),\n", " end=axes.c2p(5, 0.75),\n", " color=GREENISHWHITE)\n", "\n", " fx2 = DashedLine(start=axes.c2p(-5, 0.25),\n", " end=axes.c2p(5, 0.25),\n", " color=GREENISHWHITE)\n", "\n", "#Redefines y and fy to change their positions.\n", " point_coords = (0.65, np.sin(5*0.65/6))\n", " point_location = axes.coords_to_point(*point_coords)\n", " y = Dot(point_location, color=NEWMEDIUMGREEN)\n", "\n", " fy = DashedLine(start=axes.c2p(-5, np.sin(5*0.65/6)),\n", " end=axes.c2p(5, np.sin(5*0.65/6)),\n", " color=GREEN)\n", "\n", "#Defines a brace to show where 'epsilon' is measured and defines a label for the brace.\n", " brace = BraceBetweenPoints(axes.coords_to_point(5, np.sin(5*0.65/6)), axes.coords_to_point(5, 0.75))\n", " label = brace.get_text(r\"$\\epsilon$\")\n", "\n", "#Waits 0.5 seconds, then creates y, fy, fx1, fx2, and the brace and its label.\n", " self.wait(0.5)\n", " self.play(Create(y))\n", " self.play(Create(fy))\n", " self.play(Create(fx1))\n", " self.play(Create(fx2))\n", " self.play(Create(brace), Write(label))\n", "\n", "#Fades out the text then replaces it.\n", " self.play(FadeOut(text))\n", " text = Tex(\"If we want $|f(x) - f(y)| < \\epsilon$, where $y$ is the green dot, it is clear to see that we can choose a $\\delta$ such that when $|x-y| < \\delta$, this is true.\", font_size=20)\n", " text.move_to([0,3.5,0])\n", "\n", "#Defines fx3, fx4 and fy2, vertical lines illustrating the position of the x values at all 3 positions focused on in the animation.\n", " fx3 = DashedLine(start=axes.c2p(1, -3),\n", " end=axes.c2p(1,3),\n", " color=GREENISHWHITE)\n", "\n", " fx4 = DashedLine(start=axes.c2p(0.25, -3),\n", " end=axes.c2p(0.25, 3),\n", " color=GREENISHWHITE)\n", "\n", " fy2 = DashedLine(start=axes.c2p(0.65, -3),\n", " end=axes.c2p(0.65, 3),\n", " color=GREEN)\n", "\n", "#Defines a second brace, brace2 to show where 'delta' is measured and defines a label for the brace.\n", " brace2 = BraceBetweenPoints(axes.coords_to_point(0.65, -3), axes.coords_to_point(1, -3))\n", " label2 = Tex(\"$\\delta$\", font_size=30)\n", " label2.next_to(brace2, direction=DOWN)\n", "\n", "#Writes the text and creates fx3, fy2, fx4 and the second brace and its label.\n", " self.play(Write(text))\n", " self.play(Create(fx3))\n", " self.play(Create(fy2))\n", " self.play(Create(fx4))\n", " self.play(Create(brace2), Write(label2))\n", " self.wait()" ], "metadata": { "id": "7sf4Pu8wi4kv" }, "execution_count": 19, "outputs": [] }, { "cell_type": "markdown", "source": [ "The following command is used to render the scene and save it in the subfolder 'jupyter' in the folder 'media'." ], "metadata": { "id": "f4yiUMsCqZjg" } }, { "cell_type": "code", "source": [ "%%manim -qm -v WARNING Continuity2" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 204 }, "id": "yVqHCuMrqZ8U", "outputId": "762bf1dd-01a5-450e-91db-95598b7d14de" }, "execution_count": 20, "outputs": [ { "output_type": "display_data", "data": { "text/plain": [ "Manim Community \u001b[32mv0.\u001b[0m\u001b[32m18.1\u001b[0m\n", "\n" ], "text/html": [ "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">Manim Community <span style=\"color: #008000; text-decoration-color: #008000\">v0.18.1</span>\n", "\n", "</pre>\n" ] }, "metadata": {} }, { "output_type": "stream", "name": "stderr", "text": [] }, { "output_type": "display_data", "data": { "text/plain": [ "<IPython.core.display.Video object>" ], "text/html": [ "<video src=\"media/jupyter/Continuity2@2024-12-18@17-10-00.mp4\" controls autoplay loop style=\"max-width: 60%;\" >\n", " Your browser does not support the <code>video</code> element.\n", " </video>" ] }, "metadata": {} } ] } ] }