From ca9caba90f0325440669bca6626ee6dac98822b1 2016-11-18 14:51:43 From: Min RK Date: 2016-11-18 14:51:43 Subject: [PATCH] add example notebook --- diff --git a/examples/IPython Kernel/Updating Displays.ipynb b/examples/IPython Kernel/Updating Displays.ipynb new file mode 100644 index 0000000..ad8d912 --- /dev/null +++ b/examples/IPython Kernel/Updating Displays.ipynb @@ -0,0 +1,359 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Updatable Displays\n", + "\n", + "Note: This feature requires notebook >= 5.0 or JupyterLab, and \n", + "\n", + "\n", + "IPython 6 implements a new API as part of the Jupyter Protocol version 5.1 for easily updating displays.\n", + "\n", + "When you display something, you can now pass a `display_id` argument to attach an id to that output.\n", + "\n", + "Any future display with the same ID will also update other displays that had the same ID.\n", + "\n", + "`display` with a `display_id` will return a `DisplayHandle`\n", + "object, which gives you easy access to update the output:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from IPython.display import display, update_display" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'z'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "handle = display('x', display_id='update-me')\n", + "handle" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When we call `handle.display('y')`, we get a new display of 'y',\n", + "but in addition to that, we updated the previous display." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'z'" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "handle.display('y')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also *just* update the existing displays,\n", + "without creating a new display:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "handle.update('z')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You don't have to generate display_ids yourself,\n", + "if you specify `display_id=True`, then a unique ID will be assigned:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'hello'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "handle = display(\"hello\", display_id=True)\n", + "handle" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Calling `handle.display(obj)` is the same as calling `display(obj, handle.display_id)`,\n", + "so you don't need to use the handle objects if you don't want to:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'z'" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display('x', display_id='here');" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'z'" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display('y', display_id='here');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And just like `display`, there is now `update_display`,\n", + "which is what `DisplayHandle.update` calls:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "update_display('z', display_id='here')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## More detailed example\n", + "\n", + "One of the motivating use cases for this is simple progress bars.\n", + "\n", + "Here is an example ProgressBar using these APIs:" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " 10 / 10\n", + " " + ], + "text/plain": [ + "[============================================================] 10/10" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import os\n", + "from binascii import hexlify\n", + "\n", + "class ProgressBar(object):\n", + " def __init__(self, capacity):\n", + " self.progress = 0\n", + " self.capacity = capacity\n", + " self.html_width = '60ex'\n", + " self.text_width = 60\n", + " self._display_id = hexlify(os.urandom(8)).decode('ascii')\n", + " \n", + " def __repr__(self):\n", + " fraction = self.progress / self.capacity\n", + " filled = '=' * int(fraction * self.text_width)\n", + " rest = ' ' * (self.text_width - len(filled))\n", + " return '[{}{}] {}/{}'.format(\n", + " filled, rest,\n", + " self.progress, self.capacity,\n", + " )\n", + " \n", + " def _repr_html_(self):\n", + " return \"\"\"\n", + " {progress} / {capacity}\n", + " \"\"\".format(\n", + " progress=self.progress,\n", + " capacity=self.capacity,\n", + " width=self.html_width,\n", + " )\n", + " \n", + " def display(self):\n", + " display(self, display_id=self._display_id)\n", + " \n", + " def update(self):\n", + " update_display(self, display_id=self._display_id)\n", + "\n", + "bar = ProgressBar(10)\n", + "bar.display()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And the ProgressBar has `.display` and `.update` methods:" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " 10 / 10\n", + " " + ], + "text/plain": [ + "[============================================================] 10/10" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import time\n", + "\n", + "bar.display()\n", + "\n", + "for i in range(11):\n", + " bar.progress = i\n", + " bar.update()\n", + " time.sleep(0.25)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We would encourage any updatable-display objects that track their own display_ids to follow-suit with `.display()` and `.update()` or `.update_display()` methods." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +}