7

As referred in this question, I am trying to update a plot dynamically in an iPython notebook (in one cell). The difference is that I don't want to plot new lines, but that my x_data and y_data are growing at each iteration of some loop.

What I'd like to do is:

import numpy as np
import time
plt.axis([0, 10, 0, 100]) # supoose I know what the limits are going to be
plt.ion()
plt.show()
x = []
y = []
for i in range(10):
     x = np.append(x, i)
     y = np.append(y, i**2)
     # update the plot so that it shows y as a function of x
     time.sleep(0.5) 

but I want the plot to have a legend, and if I do

from IPython import display
import time
import numpy as np
plt.axis([0, 10, 0, 100]) # supoose I know what the limits are going to be
plt.ion()
plt.show()
x = []
y = []
for i in range(10):
    x = np.append(x, i)
    y = np.append(y, i**2)
    plt.plot(x, y, label="test")
    display.clear_output(wait=True)
    display.display(plt.gcf())
    time.sleep(0.3)
plt.legend()

I end up with a legend which contains 10 items. If I put the plt.legend() inside the loop, the legend grows at each iteration... Any solution?

1 Answer 1

7

Currently, you are creating a new Axes object for every time you plt.plot in the loop.

So, if you clear the current axis (plt.gca().cla()) before you use plt.plot, and put the legend inside the loop, it works without the legend growing each time:

import numpy as np
import time
from IPython import display

x = []
y = []
for i in range(10):
    x = np.append(x, i)
    y = np.append(y, i**2)
    plt.gca().cla() 
    plt.plot(x,y,label='test')
    plt.legend()
    display.clear_output(wait=True)
    display.display(plt.gcf()) 
    time.sleep(0.5) 

EDIT: As @tcaswell pointed out in comments, using the %matplotlib notebook magic command gives you a live figure which can update and redraw.

Sign up to request clarification or add additional context in comments.

10 Comments

Better, but if I do that, the legend is not visible until the loop has ended
One more thing: when I run my snippet (adding your line and changing legend() location), I end up with two images. Any idea why?
try switching the order of the display.clear_output and display.display lines. That is discussed in more detail in the answers to the question you linked to in the Q
You can do better if you use %matplotlib notebook which gives you a live figure that you can update and re-draw (as well as pan/zoom and have mouse+keyboard events)
Re: @P. Camilleri's comment: I added %matplotlib inline at the end of my loop (or at the end of the cell, either way worked.) as a hack to remove that second plot from appearing (when the cell ends). Switching the order of display.clear_output and display.display did not work for me. I have not yet found the correct way to use %matplotlib notebook for my dynamic plot, so this works as a temp solution in the meantime. I use %matplotlib inline everywhere else in my notebook, so resetting it probably makes sense for me anyway :-)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.