{ "metadata": { "name": "Animations_and_Progress" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Simple animations, progress bars, and clearing output" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sometimes you want to print progress in-place, but don't want\n", "to keep growing the output area. In terminals, there is the carriage-return\n", "(`'\\r'`) for overwriting a single line, but the notebook frontend does not support this\n", "behavior (yet).\n", "\n", "What the notebook *does* support is explicit `clear_output`, and you can use this to replace previous\n", "output (specifying stdout/stderr or the special IPython display outputs)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A simple example printing our progress iterating through a list:" ] }, { "cell_type": "code", "collapsed": true, "input": [ "import sys\n", "import time" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython.display import clear_output\n", "for i in range(10):\n", " time.sleep(0.25)\n", " clear_output()\n", " print i\n", " sys.stdout.flush()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The AsyncResult object has a special `wait_interactive()` method, which prints its progress interactively,\n", "so you can watch as your parallel computation completes.\n", "\n", "**This example assumes you have an IPython cluster running, which you can start from the [cluster panel](/#tab2)**" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython import parallel\n", "rc = parallel.Client()\n", "view = rc.load_balanced_view()\n", "\n", "amr = view.map_async(time.sleep, [0.5]*100)\n", "\n", "amr.wait_interactive()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also use `clear_output()` to clear figures and plots.\n", "\n", "This time, we need to make sure we are using inline pylab (**requires matplotlib**)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%pylab inline" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "from scipy.special import jn\n", "x = np.linspace(0,5)\n", "f, ax = plt.subplots()\n", "ax.set_title(\"Bessel functions\")\n", "\n", "for n in range(1,10):\n", " time.sleep(1)\n", " ax.plot(x, jn(x,n))\n", " clear_output()\n", " display(f)\n", "\n", "# close the figure at the end, so we don't get a duplicate\n", "# of the last plot\n", "plt.close()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "A Javascript Progress Bar" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`clear_output()` is still something of a hack, and if you want to do a progress bar in the notebook\n", "it is better to just use Javascript/HTML if you can.\n", "\n", "Here is a simple progress bar using HTML/Javascript:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import uuid\n", "from IPython.display import HTML, Javascript, display\n", "\n", "divid = str(uuid.uuid4())\n", "\n", "pb = HTML(\n", "\"\"\"\n", "
\n", "
 
\n", "
\n", "\"\"\" % divid)\n", "display(pb)\n", "for i in range(1,101):\n", " time.sleep(0.1)\n", " \n", " display(Javascript(\"$('div#%s').width('%i%%')\" % (divid, i)))" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The above simply makes a div that is a box, and a blue div inside it with a unique ID \n", "(so that the javascript won't collide with other similar progress bars on the same page). \n", "\n", "Then, at every progress point, we run a simple jQuery call to resize the blue box to\n", "the appropriate fraction of the width of its containing box, and voil\u00e0 a nice\n", "HTML/Javascript progress bar!" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "ProgressBar class" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And finally, here is a progress bar *class* extracted from [PyMC](http://code.google.com/p/pymc/), which will work in regular Python as well as in the IPython Notebook" ] }, { "cell_type": "code", "collapsed": true, "input": [ "import sys, time\n", "try:\n", " from IPython.display import clear_output\n", " have_ipython = True\n", "except ImportError:\n", " have_ipython = False\n", "\n", "class ProgressBar:\n", " def __init__(self, iterations):\n", " self.iterations = iterations\n", " self.prog_bar = '[]'\n", " self.fill_char = '*'\n", " self.width = 40\n", " self.__update_amount(0)\n", " if have_ipython:\n", " self.animate = self.animate_ipython\n", " else:\n", " self.animate = self.animate_noipython\n", "\n", " def animate_ipython(self, iter):\n", " print '\\r', self,\n", " sys.stdout.flush()\n", " self.update_iteration(iter + 1)\n", "\n", " def update_iteration(self, elapsed_iter):\n", " self.__update_amount((elapsed_iter / float(self.iterations)) * 100.0)\n", " self.prog_bar += ' %d of %s complete' % (elapsed_iter, self.iterations)\n", "\n", " def __update_amount(self, new_amount):\n", " percent_done = int(round((new_amount / 100.0) * 100.0))\n", " all_full = self.width - 2\n", " num_hashes = int(round((percent_done / 100.0) * all_full))\n", " self.prog_bar = '[' + self.fill_char * num_hashes + ' ' * (all_full - num_hashes) + ']'\n", " pct_place = (len(self.prog_bar) // 2) - len(str(percent_done))\n", " pct_string = '%d%%' % percent_done\n", " self.prog_bar = self.prog_bar[0:pct_place] + \\\n", " (pct_string + self.prog_bar[pct_place + len(pct_string):])\n", "\n", " def __str__(self):\n", " return str(self.prog_bar)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "p = ProgressBar(1000)\n", "for i in range(1001):\n", " p.animate(i)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }