##// END OF EJS Templates
Merge pull request #10835 from takluyver/i10814...
Merge pull request #10835 from takluyver/i10814 Identify position after a newline as the start of the next line

File last commit:

r23860:a05208da
r23981:df9b57b9 merge
Show More
Updating Displays.ipynb
313 lines | 6.2 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 [10]:
from IPython.display import display, update_display
In [13]:
handle = display('x', display_id='update-me')
handle
'z'
Out[13]:
<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 [14]:
handle.display('y')
'z'

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

In [15]:
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 [16]:
handle = display("hello", display_id=True)
handle
'hello'
Out[16]:
<DisplayHandle display_id=07fc47b2ef652ccb70addeee3eb0981a>

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 [17]:
display('x', display_id='here');
'z'
In [18]:
display('y', display_id='here');
'z'

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

In [19]:
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 [14]:
from IPython.display import ProgressBar

bar = ProgressBar(10)
bar.display()

And the ProgressBar has .display and .update methods:

In [15]:
import time

bar.display()

for i in range(11):
    bar.progress = i
    bar.update()
    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.