{ "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": 1, "metadata": {}, "outputs": [], "source": [ "from IPython.display import display, update_display" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'z'" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 2, "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": 3, "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": 4, "metadata": {}, "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": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'hello'" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 5, "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": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'z'" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display('x', display_id='here');" ] }, { "cell_type": "code", "execution_count": 7, "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": 8, "metadata": {}, "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": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "[============================================================] 10/10" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from IPython.display import ProgressBar\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": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "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": [ "The ProgressBar also has an update built into iteration:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "[============================================================] 10/10" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "for i in ProgressBar(10):\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.6.2" } }, "nbformat": 4, "nbformat_minor": 1 }