Updating Displays.ipynb
313 lines
| 6.2 KiB
| text/plain
|
TextLexer
Min RK
|
r23014 | { | ||
"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": [ | ||||
"<DisplayHandle display_id=update-me>" | ||||
] | ||||
}, | ||||
"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": [ | ||||
"<DisplayHandle display_id=07fc47b2ef652ccb70addeee3eb0981a>" | ||||
] | ||||
}, | ||||
"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", | ||||
Marius van Niekerk
|
r23860 | "execution_count": 14, | ||
Min RK
|
r23014 | "metadata": {}, | ||
"outputs": [ | ||||
{ | ||||
"data": { | ||||
"text/html": [ | ||||
Marius van Niekerk
|
r23860 | "<progress style='width:100%' max='10' value='10'></progress>" | ||
Min RK
|
r23014 | ], | ||
"text/plain": [ | ||||
Marius van Niekerk
|
r23860 | "<IPython.core.display.ProgressBar object>" | ||
Min RK
|
r23014 | ] | ||
}, | ||||
"metadata": {}, | ||||
"output_type": "display_data" | ||||
} | ||||
], | ||||
"source": [ | ||||
Marius van Niekerk
|
r23860 | "from IPython.display import ProgressBar\n", | ||
Min RK
|
r23014 | "\n", | ||
"bar = ProgressBar(10)\n", | ||||
"bar.display()" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "markdown", | ||||
"metadata": {}, | ||||
"source": [ | ||||
"And the ProgressBar has `.display` and `.update` methods:" | ||||
] | ||||
}, | ||||
{ | ||||
"cell_type": "code", | ||||
Marius van Niekerk
|
r23860 | "execution_count": 15, | ||
Min RK
|
r23014 | "metadata": {}, | ||
"outputs": [ | ||||
{ | ||||
"data": { | ||||
"text/html": [ | ||||
Marius van Niekerk
|
r23860 | "<progress style='width:100%' max='10' value='10'></progress>" | ||
Min RK
|
r23014 | ], | ||
"text/plain": [ | ||||
Marius van Niekerk
|
r23860 | "<IPython.core.display.ProgressBar object>" | ||
Min RK
|
r23014 | ] | ||
}, | ||||
"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", | ||||
Marius van Niekerk
|
r23860 | "version": "3.6.2" | ||
Min RK
|
r23014 | } | ||
}, | ||||
"nbformat": 4, | ||||
"nbformat_minor": 1 | ||||
} | ||||