[英]Animating pngs in matplotlib using ArtistAnimation
我一直在尝试为使用有限元方法为 2D 热流问题创建的一系列曲面图制作动画。 在每个时间步,我都保存了一个图而不是整个矩阵,以提高效率。
我在使用 matplotlib.animation 库中的FuncAnimation
时遇到了问题,所以我决定每次都渲染一个曲面图,将曲面图另存为 .png 文件,然后使用pyplot.imread
读取该图像。 从那里,我想将每个图像存储到一个列表中,以便我可以使用ArtistAnimation (示例)。 但是它不是做动画,而不是我得到两个单独的空白地块,然后我的面积.pngs当我打印imgplot
到屏幕上。
此外,当我尝试保存动画时,我收到以下错误消息:
AttributeError: 'module' object has no attribute 'save'.
任何有关从当前目录中读取一组 .png 文件、将它们保存在列表中、然后使用 ArtistAnimation 为这些 .png 文件“制作动画”的帮助将不胜感激。 我不需要任何花哨的东西。
(注意 - 我必须使代码自动化,所以不幸的是我不能使用外部源来为我的图像制作动画,比如 iMovie 或 ffmpeg。)
下面是我的代码:
from numpy import *
from pylab import *
import matplotlib.pyplot as plt
import matplotlib.image as mgimg
from matplotlib import animation
## Read in graphs
p = 0
myimages = []
for k in range(1, len(params.t)):
fname = "heatflow%03d.png" %p
# read in pictures
img = mgimg.imread(fname)
imgplot = plt.imshow(img)
myimages.append([imgplot])
p += 1
## Make animation
fig = plt.figure()
animation.ArtistAnimation(fig, myimages, interval=20, blit=True, repeat_delay=1000)
animation.save("animation.mp4", fps = 30)
plt.show()
问题 1:图像不显示
您需要将动画对象存储在变量中:
my_anim = animation.ArtistAnimation(fig, myimages, interval=100)
此要求特定于animation
,与matplotlib
其他绘图函数不一致,您通常可以在其中my_plot=plt.plot()
使用my_plot=plt.plot()
或plt.plot()
。
这个问题在这里进一步讨论。
问题 2:保存不起作用
没有任何animation
实例,也无法保存图形。 这是因为save
方法属于ArtistAnimation
类。 您所做的是从animation
模块调用save
,这就是引发错误的原因。
问题 3:两个窗口
最后一个问题是你会弹出两个数字。 原因是当您调用plt.imshow()
,它会在当前图形上显示一个图像,但由于尚未创建图形,因此pyplot
会为您隐式创建一个。 当 python 稍后解释fig = plt.figure()
语句时,它会创建一个新图形(另一个窗口)并将其标记为“图 2”。 将此语句移到代码的开头,可以解决该问题。
这是修改后的代码:
import matplotlib.pyplot as plt
import matplotlib.image as mgimg
from matplotlib import animation
fig = plt.figure()
# initiate an empty list of "plotted" images
myimages = []
#loops through available png:s
for p in range(1, 4):
## Read in picture
fname = "heatflow%03d.png" %p
img = mgimg.imread(fname)
imgplot = plt.imshow(img)
# append AxesImage object to the list
myimages.append([imgplot])
## create an instance of animation
my_anim = animation.ArtistAnimation(fig, myimages, interval=1000, blit=True, repeat_delay=1000)
## NB: The 'save' method here belongs to the object you created above
#my_anim.save("animation.mp4")
## Showtime!
plt.show()
(要运行上面的代码,只需将 3 个图像添加到您的工作文件夹中,名称为“heatflow001.png”到“heatflow003.png”。)
使用FuncAnimation
替代方法
当您第一次尝试使用FuncAnimation
时,您可能是对的,因为在列表中收集图像会占用大量内存。 我通过比较系统监视器上的内存使用情况,针对上面的代码测试了下面的代码。 看起来FuncAnimation
方法更有效。 我相信随着您使用更多图像,差异会变得更大。
这是第二个代码:
from matplotlib import pyplot as plt
from matplotlib import animation
import matplotlib.image as mgimg
import numpy as np
#set up the figure
fig = plt.figure()
ax = plt.gca()
#initialization of animation, plot array of zeros
def init():
imobj.set_data(np.zeros((100, 100)))
return imobj,
def animate(i):
## Read in picture
fname = "heatflow%03d.png" % i
## here I use [-1::-1], to invert the array
# IOtherwise it plots up-side down
img = mgimg.imread(fname)[-1::-1]
imobj.set_data(img)
return imobj,
## create an AxesImage object
imobj = ax.imshow( np.zeros((100, 100)), origin='lower', alpha=1.0, zorder=1, aspect=1 )
anim = animation.FuncAnimation(fig, animate, init_func=init, repeat = True,
frames=range(1,4), interval=200, blit=True, repeat_delay=1000)
plt.show()
@snake_charmer 答案对我有用,除了 save()(问题 2:Save 不起作用)
如果您使用这样的作家,它会起作用:
Writer = animation.writers['ffmpeg']
writer = Writer(fps=15, metadata=dict(artist='Me'), bitrate=1800)
my_anim.save("animation.mp4", writer=writer)
请参阅: https : //matplotlib.org/gallery/animation/basic_example_writer_sgskip.html
在 Mac 上,您可能需要在自制软件上安装 FFmpeg: https : //apple.stackexchange.com/questions/238295/installing-ffmpeg-with-homebrew
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.