Updatable Displays¶
Note: This feature requires notebook >= 5.0 or JupyterLab, and
IPython 6 implements a new API as part of the Jupyter Protocol version 5.1 for easily updating displays.
When you display something, you can now pass a display_id
argument to attach an id to that output.
Any future display with the same ID will also update other displays that had the same ID.
display
with a display_id
will return a DisplayHandle
object, which gives you easy access to update the output:
from IPython.display import display, update_display
handle = display('x', display_id='update-me')
handle
When we call handle.display('y')
, we get a new display of 'y',
but in addition to that, we updated the previous display.
handle.display('y')
We can also just update the existing displays, without creating a new display:
handle.update('z')
You don't have to generate display_ids yourself,
if you specify display_id=True
, then a unique ID will be assigned:
handle = display("hello", display_id=True)
handle
Calling handle.display(obj)
is the same as calling display(obj, handle.display_id)
,
so you don't need to use the handle objects if you don't want to:
display('x', display_id='here');
display('y', display_id='here');
And just like display
, there is now update_display
,
which is what DisplayHandle.update
calls:
update_display('z', display_id='here')
More detailed example¶
One of the motivating use cases for this is simple progress bars.
Here is an example ProgressBar using these APIs:
from IPython.display import ProgressBar
bar = ProgressBar(10)
bar.display()
And the ProgressBar has .display
and .update
methods:
import time
bar.display()
for i in range(11):
bar.progress = i
bar.update()
time.sleep(0.25)
The ProgressBar also has an update built into iteration:
for i in ProgressBar(10):
time.sleep(0.25)
We would encourage any updatable-display objects that track their own display_ids to follow-suit with .display()
and .update()
or .update_display()
methods.