{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "d6b262ad", "metadata": {}, "source": [ "# Animation inside a Jupyter notebook\n", "\n", "Next to (plain or enhanced) MarkDown, Jupyter books can also contain chapters which are essentially Jupyter Notebooks. The current file is an example, in which I've created an animation in a Jupyter Notebook, which plots the sine/cosine and their phase plane over time.\n", "\n", "Source: [colab Google](https://colab.research.google.com/github/jckantor/CBE30338/blob/master/docs/A.03-Animation-in-Jupyter-Notebooks.ipynb)" ] }, { "cell_type": "markdown", "id": "d59623b5", "metadata": {}, "source": [ "## Step 1: Background frame" ] }, { "cell_type": "code", "execution_count": 1, "id": "2e2fa36f", "metadata": { "scrolled": true }, "outputs": [ { "data": { "image/png": "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5T6Nqzlj/a/sC980li1bZvj6+hrJycnG999/b4wZM8YICgoysrOzDcMwjEceecSYMmWKtf9XX31l1KhRw5g7d65x8OBBY9q0aUbNmjWNffv2WfvMmjXLCAoKMtasWWN89913Rt++fY2IiAjjv//9r1vOadasWYaPj4/x8ccfG6dPn7beLly4YBiGYVy4cMF46qmnjLS0NCMjI8PYtGmTcccddxitW7c2Ll++7JZzmj59urFhwwbj2LFjxu7du43Bgwcbfn5+xoEDB2zm7Unb6Zp77rnHGDRoUKl2V2+nCxcuGHv37jX27t1rSDJeffVVY+/evcaJEycMwzCMKVOmGI888oi1/w8//GD4+/sbf/7zn42DBw8aCxYsMLy9vY3169db+1zvPXK3OX344YdGjRo1jAULFtj8LOXm5lr7TJ482UhNTTUyMjKMr776yoiLizMaNmxonDlzxi3nNG/ePGP16tXGkSNHjH379hlPPvmk4eXlZWzatMnax9O20zUPP/yw0aVLlzKf05XbaezYsUZgYKCRmppq8zm6dOmStY8nrk3u7tSpU0arVq2MHj16GKdOnbJ573/Zp23btsaOHTusbY899pjRtGlTY/PmzcauXbuMmJgYIyYmxhVTKNOJEyeMvXv3GtOnTzfq1Klj/Vm5tsYbhmG0bdvWWLlypWEYrl9LKqOqczIM9/789+7d2+jYsaOxY8cO48svvzRat25tDBkyxPr4rz93R48eNV544QVj165dRkZGhrFmzRqjRYsWxn333eeS+p2xL+1qztjvdDVn7Ke5mjP2aVzJWev/9dxU4d8wDOONN94wmjZtavj4+BidO3c2vv76a+tjXbt2NYYPH27T/5///KfRpk0bw8fHx7jtttuMf/3rXzaPl5SUGM8995wREhJi+Pr6Gj169DAOHz5cHVOxqsqcmjVrZkgqdZs2bZphGIZx6dIlo1evXkZwcLBRs2ZNo1mzZsbo0aOrbcfenjlNnDjR2jckJMT43e9+Z+zZs8fm+TxtOxmGYRw6dMiQZHz++eelnsvV2+nan0/59e3aHIYPH2507dq11JgOHToYPj4+RosWLYzFixeXet6K3iNnq+qcunbtWmF/w/j5z+SEhYUZPj4+xi233GIMGjTIOHr0qNvOafbs2UbLli0NPz8/o379+ka3bt2MzZs3l3peT9pOhvHzn/mqVauWsWjRojKf05Xbqay5SLL5+fDUtcmdLV68uNz3/pqMjAxDkrFlyxZr23//+1/j8ccfN+rVq2f4+/sbv//9721+YeBqw4cPL3NOv5zDLz9frl5LKqOqczIM9/78nzt3zhgyZIhRp04dIyAgwBgxYoTNLzJ+/bnLzMw07rvvPqN+/fqGr6+v0apVK+PPf/6zkZeX56IZOH5f2h04er/T1Zy1n+ZKztqncRVnrf/XY/l/Lw4AAAAAAEzqpvnOPwAAAAAANyvCPwAAAAAAJkf4BwAAAADA5Aj/AAAAAACYHOEfAAAAAACTI/wDAAAAAGByhH8AAAAAAEyO8A8AAAAAgMkR/gE4TGJiohISElxdBgAAAIBfIfwDqBSLxVLh7fnnn9frr7+u5ORkV5cKAACqSXFxsWJjY9WvXz+b9ry8PIWHh+uvf/2riyoD8GsWwzAMVxcBwP1lZ2db/718+XJNnTpVhw8ftrbVqVNHderUcUVpAADAhf7973+rQ4cOevvttzV06FBJ0rBhw/Ttt9/qm2++kY+Pj4srBCBx5B9AJYWGhlpvgYGBslgsNm116tQpddp/t27dNGHCBE2cOFH16tVTSEiI3n77bRUUFGjEiBGqW7euWrVqpc8++8zmtfbv368+ffqoTp06CgkJ0SOPPKKffvqpmmcMAAAqo02bNpo1a5YmTJig06dPa82aNVq2bJmWLFlC8AfcCOEfgFO99957atiwoXbu3KkJEyZo7NixGjBggGJjY7Vnzx716tVLjzzyiC5duiRJys3N1W9/+1t17NhRu3bt0vr165WTk6OBAwe6eCYAAKA8EyZMUHR0tB555BGNGTNGU6dOVXR0tKvLAvALnPYPoMqSk5M1ceJE5ebm2rQnJiYqNzdXq1evlvTzkf/i4mJ98cUXkn7+XmBgYKD69eunJUuWSPr56wRhYWFKS0vTXXfdpZdeeklffPGFNmzYYH3eU6dOKTw8XIcPH1abNm2qZY4AAKBqDh06pHbt2ikqKkp79uxRjRo1XF0SgF/gyD8Ap2rfvr31397e3mrQoIGioqKsbSEhIZKkM2fOSJK+/fZbbdmyxXoNgTp16igyMlKSdOzYsWqsHAAAVMW7774rf39/ZWRk6NSpU64uB8Cv8Os4AE5Vs2ZNm/sWi8WmzWKxSJJKSkokSRcvXtQDDzyg2bNnl3qusLAwJ1YKAADstX37ds2bN0+ff/65XnrpJY0cOVKbNm2yrvMAXI/wD8Ct3HHHHfrkk0/UvHlzThcEAMADXLp0SYmJiRo7dqy6d++uiIgIRUVFaeHChRo7dqyrywPw/3DaPwC3Mm7cOJ0/f15DhgzRN998o2PHjmnDhg0aMWKEiouLXV0eAAD4laSkJBmGoVmzZkmSmjdvrrlz5+rpp5/W8ePHXVscACvCPwC30rhxY3311VcqLi5Wr169FBUVpYkTJyooKEheXvwvCwAAd7J161YtWLBAixcvlr+/v7X90UcfVWxsrEaOHCmuLw64B672DwAAAACAyXEYDQAAAAAAkyP8AwAAAABgcoR/AAAAAABMjvAPAAAAAIDJEf4BAAAAADA5wj8AAAAAACZH+AcAAAAAwOQI/wAAAAAAmBzhHwAAAAAAkyP8AwAAAABgcoR/AAAAAABM7v8CzLzmlq3ZbZYAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%matplotlib inline\n", "\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "# Create a figure and axes.\n", "fig = plt.figure(figsize=(12,5))\n", "ax1 = plt.subplot(1,2,1)\n", "ax2 = plt.subplot(1,2,2)\n", "\n", "# Set up the subplots\n", "ax1.set_xlim((0,2))\n", "ax1.set_ylim((-2,2))\n", "ax1.set_xlabel('Time')\n", "ax1.set_ylabel('Magnitude')\n", "\n", "ax2.set_xlim((-2,2))\n", "ax2.set_ylim((-2,2))\n", "ax2.set_xlabel('X')\n", "ax2.set_ylabel('Y')\n", "ax2.set_title('Phase plane')\n", "\n", "# Create objects that will change in the animiation.\n", "# These objects are initially empty, and will be given new values for each frame in the animation.\n", "txt_title = ax1.set_title('')\n", "line1, = ax1.plot([], [], 'b', lw=2) # ax.plot returns a list of 2D line objects.\n", "line2, = ax1.plot([], [], 'r', lw=2)\n", "pt1, = ax2.plot([], [], 'g.', ms=20)\n", "line3, = ax2.plot([], [], 'y', lw=2)\n", "\n", "ax1.legend(['sin', 'cos']);" ] }, { "attachments": {}, "cell_type": "markdown", "id": "0abad94b", "metadata": {}, "source": [ "## Step 2: Define a function to draw each frame" ] }, { "cell_type": "code", "execution_count": 2, "id": "94c52da2", "metadata": {}, "outputs": [], "source": [ "# Animation function. This function is called sequentially.\n", "def drawframe(n):\n", " x = np.linspace(0, 2, 1000)\n", " y1 = np.sin(2 * np.pi * (x - 0.01 * n))\n", " y2 = np.cos(2 * np.pi * (x - 0.01 * n))\n", " line1.set_data(x, y1)\n", " line2.set_data(x, y2)\n", " line3.set_data(y1[0:50],y2[0:50])\n", " pt1.set_data([y1[0]], [y2[0]]) # Note that matplotlib will throw an error if we supply only numbers (i.e., pt1.set_data(y1[0],y2[0]))\n", " txt_title.set_text('Frame = {0:4d}'.format(n))\n", " return (line1,line2)" ] }, { "cell_type": "code", "execution_count": 3, "id": "0b43bb20", "metadata": {}, "outputs": [], "source": [ "# Initialization function.\n", "def init():\n", " line1.set_data([],[])\n", " line2.set_data([],[])\n", " return(line1, line2)" ] }, { "cell_type": "markdown", "id": "8828ac05", "metadata": {}, "source": [ "## Step 3: Create the animation object" ] }, { "cell_type": "code", "execution_count": 4, "id": "31b1d607", "metadata": {}, "outputs": [], "source": [ "from matplotlib import animation\n", "\n", "#anim = animation.FuncAnimation(fig, drawframe, init_func=init, frames=100, interval=20, blit=True)\n", "anim = animation.FuncAnimation(fig, drawframe, frames=100, interval=20, blit=True)\n", "# blit = True re-draws only the parts that have changed." ] }, { "cell_type": "markdown", "id": "ce10e51b", "metadata": {}, "source": [ "## Step 4 (JavaScript version)\n", "Use HTML(anim.to_jshtml())\n", "See [Stackoverflow inline animations in Jupyter](https://stackoverflow.com/questions/43445103/inline-animations-in-jupyter#43447370). Note that this takes some time to parse." ] }, { "cell_type": "code", "execution_count": 5, "id": "c664b39c", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n", " \n", "
\n", " \n", "
\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
\n", "
\n", " \n", " \n", " \n", " \n", " \n", " \n", "
\n", "
\n", "
\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import HTML\n", "HTML(anim.to_jshtml())" ] } ], "metadata": { "interpreter": { "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49" }, "kernelspec": { "display_name": "Python 3.10.4 64-bit", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.2" } }, "nbformat": 4, "nbformat_minor": 5 }