5

Edit: My question is not in regards to an "animation" per se. My question here, is simply about how to continuously show, a new inline image, in a for loop, within an Ipython notebook.

In essence, I would like to show an updated image, at the same location, inline, and have it update within the loop to show. So my code currently looks something like this:

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from IPython import display
%matplotlib inline  

fig, ax = plt.subplots(nrows = 1, ncols = 1, figsize=(10, 10))
for ii in xrange(10):
    im = np.random.randn(100,100)
    ax.cla()
    ax.imshow(im, interpolation='None')
    ax.set_title(ii)
    plt.show()

The problem is that this currently just..., well, shows the first image, and then it never changes.

Instead, I would like it to simply show the updated image at each iteration, inline, at the same place. How do I do that? Thanks.

TheGrapeBeyond
  • 543
  • 2
  • 8
  • 19
  • Executing this, I get: `ax[0].cla(): TypeError: 'AxesSubplot' object does not support indexing` – bastelflp Nov 05 '17 at 18:14
  • @bastelflp Sorry, try it now. – TheGrapeBeyond Nov 05 '17 at 18:15
  • 1
    I do not believe this is a duplicate, as this pertains to numpy arrays being shown in a loop. It has nothing to do with an "animation" per se. – TheGrapeBeyond Nov 05 '17 at 22:12
  • The lines `matplotlib.use('TkAgg')` and `%matplotlib inline` conflict as they refer to different backends. Do you want an inline image or a separate window? – Pierre de Buyl Nov 07 '17 at 09:08
  • @PierredeBuyl Good point. I would like to update the inline image. – TheGrapeBeyond Nov 07 '17 at 15:58
  • I am not sure that you can do this without animation. Notebooks capture the output of matplotlib to include in the cell once the plotting is over. The animation framework is rather generic and covers anything that is not a static image. [matplotlib.animation.FuncAnimation](http://matplotlib.org/api/_as_gen/matplotlib.animation.FuncAnimation.html#matplotlib.animation.FuncAnimation) would probably do what you want. – Pierre de Buyl Nov 07 '17 at 18:02
  • @PierredeBuyl Thanks, could you write an answer, and then I can accept it? Thanks! – TheGrapeBeyond Nov 10 '17 at 00:39

2 Answers2

3

I am not sure that you can do this without animation. Notebooks capture the output of matplotlib to include in the cell once the plotting is over. The animation framework is rather generic and covers anything that is not a static image. matplotlib.animation.FuncAnimation would probably do what you want.

I adapted your code as follows:

%matplotlib notebook
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation

f = plt.figure()
ax = f.gca()

im = np.random.randn(100,100)
image = plt.imshow(im, interpolation='None', animated=True)

def function_for_animation(frame_index):
    im = np.random.randn(100,100)
    image.set_data(im)
    ax.set_title(str(frame_index))
    return image,

ani = matplotlib.animation.FuncAnimation(f, function_for_animation, interval=200, frames=10, blit=True)

Note: You must restart the notebook for the %matplotlib notebook to take effect and use a backend that supports animation.

EDIT: There is normally a way that is closer to your original question but it errors on my computer. In the example animation_demo there is a plain "for loop" with a plt.pause(0.5) statement that should also work.

Pierre de Buyl
  • 7,074
  • 2
  • 16
  • 22
1

You can call figure.canvas.draw() each time you append something new to the figure. This will refresh the plot (from here). Try:

import numpy as np
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from IPython import display
from time import sleep

fig = plt.figure()
ax = fig.gca()
fig.show()

for ii in range(10):
    im = np.random.randn(100, 100)
    plt.imshow(im, interpolation='None')
    ax.set_title(ii)
    fig.canvas.draw()
    sleep(0.1)

I could not test this in an IPython Notebook, however.

bastelflp
  • 9,362
  • 7
  • 32
  • 67