我创建了一个'plotter(x)'函数,它读取pd.DataFrame
中的时间序列并返回由两个轴组成的图形(return fig
)。一个是pyplot.figure.add_subplot(111)
,我在其中添加descartes.PolygonPatch(shapely.Polygon(y))
- es。第二个是pyplot.figure.add_axes
,其中包含带有自定义色彩映射的颜色条。
我需要第二个功能来制作一部电影,以2 fps的速率显示时间序列中每个时间步的图。我这样做了:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
def video_plotter(rain_series):
fig = plt.figure()
ims = []
for i in (range(len(rain_series.columns)-1)):
fig = plotter(rain_series[[rain_series.columns[i], rain_series.columns[-1]]])
ims.append([fig])
ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True,repeat_delay=1000)
writer = animation.MencoderFileWriter(fps=2)
ani.save('demo.mp4',writer=writer,dpi=100)
问题1:我该怎么做才能使这项工作?
我知道一个选项是循环应用我已经拥有的函数创建一系列.png-s的时间序列,然后直接在unix终端中使用mencoder来创建.avi。然而,颜色条和被映射的形状多边形的大多数值不随时间变化,并且每次需要绘制时消耗大量计算。另外,我需要添加一个不会改变的mpl_toolkits.basemap.Basemap
。这使得'.png-series'方法不方便。我也不能使用sys
导入:我需要在Python中做所有事情。
我需要在matplotlib.animation中使用blit=True
来避免重绘特征,如果它们在先前帧中是相同的。它是否也适用于底图?
问题2:如何在视频中集成静态底图?
答案 0 :(得分:4)
您似乎必须以不同方式安排代码才能使其正常工作。动画代码的总体布局由两部分组成:
<强> 1。创建情节的静态内容
在此步骤中,您将创建图形,添加子图,绘制所有静态内容(例如底图),并且通常添加第一个数据集或一些兼容的虚拟数据。
<强> 2。更新每个框架
对于每个动画帧,您通常只需更新动态数据而无需创建任何新对象。如果您有图像,则可以使用imobj = ax.imshow(img)
在步骤1中创建图像。在此更新步骤中,您不会创建新图像,只需按imobj.set_array(newdata)
更新图像数据。 (这就是说,可以创建新对象,但您需要记住删除不需要的对象。)
当然,这不仅限于图像,yuo可能会改变绘制的线条,曲面,补丁等背后的数据。
Blitting与此没有任何关系,只是为了让事情更快(并且不适用于所有后端)。如果你不需要实时显示动画,那么关闭blitting可能会更安全。
我的建议是,在考虑上述情况后重写plotter
。
仅举例说明如何制作动画:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation
# update the data for each frame
def anim(n):
global data
# get some new data
data += np.random.random((100,100)) - .5
# update the data into the image
imobj.set_array(data)
# returns a list of drawables which have been changed (needed for blitting)
return imobj,
# create the figure
fig = plt.figure()
ax = fig.add_subplot(111)
# plot a static image
x = np.linspace(0, 2*np.pi, 200)
ax.plot(x, np.sin(x), 'r', lw=2)
# some data
data = np.random.random((100,100)) - .5
# create the image on top
imobj = ax.imshow(data, extent=[0,2*np.pi, -1.2, 1.2], origin='lower', cmap=plt.cm.gray, vmin=-2, vmax=2, alpha=.7, zorder=10)
# create the animation
ani = matplotlib.animation.FuncAnimation(fig, anim, frames=100)
ani.save("/tmp/test.mp4", fps=10, codec="libx264", extra_args=['-pix_fmt', 'yuv420p'])
这会产生一个动画,其中前景中的半透明图像会发生变化,后面会出现静态图像。 (如果您在尝试时遇到问题,可以将codec
和extra_args
关键字保留,因为他们需要您安装libx264。)
电影的最后一帧: