简体   繁体   中英

Animate a 3D matrix with Matplotlib in Jupyter Notebook

I have a 3D matrix of shape (100,50,50), eg

import numpy as np
data = np.random.random(100,50,50)

And I want to create an animation that shows each of the 2D slices of size (50,50) as a heatmap or imshow

eg:

import matplotlib.pyplot as plt

plt.imshow(data[0,:,:])
plt.show()

would display the 1st 'frame' of this animation. I'd like to also have this display in a Jupyter Notebook. I am currently following this tutorial for inline notebook animations being displayed as a html video, but I can't figure out how to replace the 1D line data with a slice of my 2D array.

I know I need to create a plot element, an initialisation function and an animate function. Following that example, I've tried:

fig, ax = plt.subplots()

ax.set_xlim((0, 50))
ax.set_ylim((0, 50))

im, = ax.imshow([])

def init():
    im.set_data([])
    return (im,)

# animation function. This is called sequentially
def animate(i):
    data_slice = data[i,:,:]
    im.set_data(i)
    return (im,)

# call the animator. blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=100, interval=20, blit=True)

HTML(anim.to_html5_video())

But I'm getting various errors whatever I try, mostly associated with the line im, = ax.imshow([])

Any help appreciated!

Several issues:

  1. You have a lot of missing imports.
  2. numpy.random.random takes a tuple as input, not 3 arguments
  3. imshow needs an array as input, not an empty list.
  4. imshow returns an AxesImage , which cannot be unpacked. Hence no , on the assignment.
  5. .set_data() expects the data, not the framenumber as input.

Complete code:

from IPython.display import HTML
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

data = np.random.rand(100,50,50)

fig, ax = plt.subplots()

ax.set_xlim((0, 50))
ax.set_ylim((0, 50))

im = ax.imshow(data[0,:,:])

def init():
    im.set_data(data[0,:,:])
    return (im,)

# animation function. This is called sequentially
def animate(i):
    data_slice = data[i,:,:]
    im.set_data(data_slice)
    return (im,)

# call the animator. blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=100, interval=20, blit=True)

HTML(anim.to_html5_video())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM