2

我制作了一个“绘图仪(x)”函数,它读取 a 中的时间序列并返回由两个轴组成pd.DataFrame的图形( )。return fig一个是 a pyplot.figure.add_subplot(111),我在其中添加descartes.PolygonPatch(shapely.Polygon(y))-es。第二个是 a 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 中做所有事情。

我需要blit=True在 matplotlib.animation 中使用以避免重绘特征,如果它们在前一个框架中是相同的。它也适用于底图吗?

问题 2:如何在视频中集成静态底图?

4

1 回答 1

4

看来您必须以不同的方式安排代码才能使其正常工作。动画代码的总体布局由两部分组成:

1. 剧情静态内容的创建

在此步骤中,您将创建图形、添加子图、绘制所有静态内容(例如底图),并且通常会添加第一个数据集或一些兼容的虚拟数据。

2.更新每一帧

对于每个动画帧,您通常只需更新动态数据而不创建任何新对象。例如,如果您有一个图像,那么您已经在步骤 1 中使用imobj = ax.imshow(img). 在此更新步骤中,您不会创建新图像,而只需将图像数据更新为 imobj.set_array(newdata). (话虽如此,可以创建新对象,但您需要记住删除不需要的对象。)

当然,这不仅限于图像,您可能会更改绘制线、曲面、补丁等后面的数据。

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'])

这给出了一个动画,其中前景中的半透明图像发生变化,而后部则为静态图像。(如果您在尝试时遇到问题,您可以省略codecandextra_args关键字,因为它们需要您安装 libx264。)

影片最后一帧:

在此处输入图像描述

于 2014-08-26T11:34:54.020 回答