Home > Enterprise >  Animating a figure of subplots of multiple image series
Animating a figure of subplots of multiple image series

Time:10-13

Most questions about the animation of matplotlib items details the plotting of data in line format, which does not seem to work for images.

I have three series of images that I want to show in subplots, and animate the figure to show each item in the series. Currently I create the figure with subplots and in a for loop, generate a list of figures I want to show in the animation. I am using a jupyter notebook so I export this to a jshtml frame. My code:

fig, (ax0, ax1, ax2) = plt.subplots(nrows=1, ncols=3,
                                    figsize=(12, 6))
fis = []
for i in range(0,len(filename_list),4): #show every 4th image in series

    ax0.set_title('Raw image')
    ax0.imshow(plt.imread(filename_list[i]),animated=True)
    ax1.set_title('Manually cropped image')
    ax1.imshow(plt.imread(  (filename_list[i].parent / 'cropped' /filename_list[i].name)  ) ,animated=True)
    ax2.set_title('Cropped image after re-centering')
    ax2.imshow(plt.imread(  (filename_list[i].parent / 'cropped_corr' /filename_list[i].name)  ) ,animated=True)

    fis.append([fig])

ani = animation.ArtistAnimation(fig, fis, interval=500, blit=False, repeat_delay=1000)
plt.close()

HTML(ani.to_jshtml())

This yields a working jshtml animation, but the subplots do not change. How can I animate this so that the subplots update? I cannot work out how to make an animation function that updates each frame.

Thanks!

CodePudding user response:

Shortly after posting I re-examined the code for creating only one image in the animation. It occurred to me that I needed to set each imshow command as a variable which is added to the list of figures. The code becomes:

fig, (ax0, ax1, ax2) = plt.subplots(nrows=1, ncols=3,
                                    figsize=(12, 6))
fis = []
for i in range(0,len(filename_list),4):

    ax0.set_title('Raw image')
    im0=ax0.imshow(plt.imread(filename_list[i]),animated=True)
    ax1.set_title('Manually cropped image')
    im1=ax1.imshow(plt.imread(  (filename_list[i].parent / 'cropped' /filename_list[i].name)  ) ,animated=True)
    ax2.set_title('Cropped image after re-centering')
    im2=ax2.imshow(plt.imread(  (filename_list[i].parent / 'cropped_corr' /filename_list[i].name)  ) ,animated=True)

    fis.append([im0,im1,im2])

ani = animation.ArtistAnimation(fig, fis, interval=500, blit=False, repeat_delay=1000)
plt.close()

HTML(ani.to_jshtml())

Note the addition of im0, im1, im2 to each imshow call and in the fis.append command creating a list of lists.

CodePudding user response:

from IPython.display import clear_output
fis = []
for i in range(0,len(filename_list),4): #show every 4th image in series
    fig, (ax0, ax1, ax2) = plt.subplots(nrows=1, ncols=3, figsize=(12, 6), num = 1, clear = True)
    ax0.set_title('Raw image')
    ax0.imshow(plt.imread(filename_list[i]),animated=True)
    ax1.set_title('Manually cropped image')
    ax1.imshow(plt.imread(  (filename_list[i].parent / 'cropped' /filename_list[i].name)  ) ,animated=True)
    ax2.set_title('Cropped image after re-centering')
    ax2.imshow(plt.imread(  (filename_list[i].parent / 'cropped_corr' /filename_list[i].name)  ) ,animated=True)
    plt.show()

    fis.append([fig])
    clear_output()

ani = animation.ArtistAnimation(fig, fis, interval=500, blit=False, repeat_delay=1000)

HTML(ani.to_jshtml())
  • Related