What is the currently correct way to dynamically update plots in Jupyter/iPython?

In the answers to how to dynamically update a plot in a loop in ipython notebook (within one cell), an example is given of how to dynamically update a plot inside a Jupyter notebook within a Python loop. However, this works by destroying and re-creating the plot on every iteration, and a comment in one of the threads notes that this situation can be improved by using the new-ish %matplotlib nbagg magic, which provides an interactive figure embedded in the notebook, rather than a static image.

However, this wonderful new nbagg feature seems to be completely undocumented as far as I can tell, and I'm unable to find an example of how to use it to dynamically update a plot. Thus my question is, how does one efficiently update an existing plot in a Jupyter/Python notebook, using the nbagg backend? Since dynamically updating plots in matplotlib is a tricky issue in general, a simple working example would be an enormous help. A pointer to any documentation on the topic would also be extremely helpful.

To be clear what I'm asking for: what I want to do is to run some simulation code for a few iterations, then draw a plot of its current state, then run it for a few more iterations, then update the plot to reflect the current state, and so on. So the idea is to draw a plot and then, without any interaction from the user, update the data in the plot without destroying and re-creating the whole thing.

Here is some slightly modified code from the answer to the linked question above, which achieves this by re-drawing the whole figure every time. I want to achieve the same result, but more efficiently using nbagg.

    %matplotlib inline
    import time
    import pylab as pl
    from IPython import display
    for i in range(10):
        pl.clf()
        pl.plot(pl.randn(100))
        display.display(pl.gcf())
        display.clear_output(wait=True)
        time.sleep(1.0)

Here is an example that updates a plot in a loop. It updates the data in the figure and does not redraw the whole figure every time. It does block execution, though if you're interested in running a finite set of simulations and saving the results somewhere, it may not be a problem for you.

    %matplotlib notebook

    import numpy as np
    import matplotlib.pyplot as plt
    import time

    def pltsin(ax, colors=['b']):
        x = np.linspace(0,1,100)
        if ax.lines:
            for line in ax.lines:
                line.set_xdata(x)
                y = np.random.random(size=(100,1))
                line.set_ydata(y)
        else:
            for color in colors:
                y = np.random.random(size=(100,1))
                ax.plot(x, y, color)
        fig.canvas.draw()

    fig,ax = plt.subplots(1,1)
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_xlim(0,1)
    ax.set_ylim(0,1)
    for f in range(5):
        pltsin(ax, ['b', 'r'])
        time.sleep(1)

I put this up on nbviewer here.

There is an IPython Widget version of nbagg that is currently a work in progress at the Matplotlib repository. When that is available, that will probably be the best way to use nbagg.

EDIT: updated to show multiple plots

From: stackoverflow.com/q/34486642