##// END OF EJS Templates
Statically type OInfo. (#13973)...
Statically type OInfo. (#13973) In view of working with #13860, some cleanup inspect to be properly typed, and using stricter datastructure. Instead of dict we now use dataclasses, this will make sure that fields type and access can be stricter and verified not only at runtime, but by mypy

File last commit:

r23943:84bcdc34
r28166:29b451fc merge
Show More
Updating Displays.ipynb
337 lines | 6.8 KiB | text/plain | TextLexer

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:

In [1]:
from IPython.display import display, update_display
In [2]:
handle = display('x', display_id='update-me')
handle
'z'
Out[2]:
<DisplayHandle display_id=update-me>

When we call handle.display('y'), we get a new display of 'y', but in addition to that, we updated the previous display.

In [3]:
handle.display('y')
'z'

We can also just update the existing displays, without creating a new display:

In [4]:
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:

In [5]:
handle = display("hello", display_id=True)
handle
'hello'
Out[5]:
<DisplayHandle display_id=118a56127f42348f8893440da7181c57>

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:

In [6]:
display('x', display_id='here');
'z'
In [7]:
display('y', display_id='here');
'z'

And just like display, there is now update_display, which is what DisplayHandle.update calls:

In [8]:
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:

In [9]:
from IPython.display import ProgressBar

bar = ProgressBar(10)
bar.display()

And the ProgressBar has .display and .update methods:

In [10]:
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:

In [11]:
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.