【问题标题】:Saving scatterplot animations with matplotlib produces blank video file使用 matplotlib 保存散点图动画会产生空白视频文件
【发布时间】:2013-03-15 23:47:45
【问题描述】:

我遇到了与this question 非常相似的问题

但建议的解决方案对我不起作用。

我已经使用 matplotlib 动画模块设置了一个动画散点图。这在实时显示时工作正常。我想将它保存到 avi 文件或类似的文件中。我为此编写的代码不会出错,但它产生的视频只显示一组空白轴或黑屏。我已经做了几项检查,数据正在运行并且图已更新,只是没有保存到视频中......

我尝试按照this question 中的建议删除“animated=True”和“blit=True”,但这并没有解决问题。

我已将相关代码放在下面,但如有必要可以提供更多。谁能建议我应该怎么做才能使它正常工作?

def initAnimation(self):
        rs, cfgs = next(self.jumpingDataStreamIterator)     
        #self.scat = self.axAnimation.scatter(rs[0], rs[1], c=cfgs[0], marker='o')
        self.scat = self.axAnimation.scatter(rs[0], rs[1], c=cfgs[0], marker='o', animated=True)
        return self.scat,


def updateAnimation(self, i):
    """Update the scatter plot."""
    rs, cfgs = next(self.jumpingDataStreamIterator)
    # Set x and y data...
    self.scat.set_offsets(rs[:2,].transpose()) 
    #self.scat = self.axAnimation.scatter(rs[0], rs[1], c=cfgs[0], animated=True)
    # Set sizes...
    #self.scat._sizes = 300 * abs(data[2])**1.5 + 100
    # Set colors..
    #self.scat.set_array(cfgs[0])
    # We need to return the updated artist for FuncAnimation to draw..
    # Note that it expects a sequence of artists, thus the trailing comma.
    matplotlib.pyplot.draw()
    return self.scat,

def animate2d(self, steps=None, showEvery=50, size = 25):
    self.figAnimation, self.axAnimation = matplotlib.pyplot.subplots()
    self.axAnimation.set_aspect("equal")
    self.axAnimation.axis([-size, size, -size, size])
    self.jumpingDataStreamIterator = self.jumpingDataStream(showEvery)

    self.univeseAnimation = matplotlib.animation.FuncAnimation(self.figAnimation, 
                            self.updateAnimation, init_func=self.initAnimation,
                            blit=True)
    matplotlib.pyplot.show()

def animate2dVideo(self,fileName=None, steps=10000, showEvery=50, size=25):
    self.figAnimation, self.axAnimation = matplotlib.pyplot.subplots()
    self.axAnimation.set_aspect("equal")
    self.axAnimation.axis([-size, size, -size, size])
    self.Writer = matplotlib.animation.writers['ffmpeg']
    self.writer = self.Writer(fps=1, metadata=dict(artist='Universe Simulation'))
    self.jumpingDataStreamIterator = self.jumpingDataStream(showEvery)

    self.universeAnimation = matplotlib.animation.FuncAnimation(self.figAnimation, 
                            self.updateAnimation, scipy.arange(1, 25), init_func=self.initAnimation)

    self.universeAnimation.save('C:/universeAnimation.mp4', writer = self.writer)

【问题讨论】:

  • 您能否将其减少到重现问题所需的最少代码量?这显然是一个更大类的一部分,并且不清楚它是否可以作为独立代码起作用。请帮助我们为您提供帮助。
  • stackoverflow.com/a/14740703/380231 中的 exact 代码在您的系统上运行是否有效?
  • 抱歉耽搁了。我找到了一种解决方法,只需保存大量单独的图像,然后调用 ffmpeg 将它们链接在一起。这并不理想,但可以完成工作。当我在这里运行代码stackoverflow.com/a/14740703/380231 时,出现以下错误: .... 文件“C:\Python27\lib\site-packages\matplotlib\backend_bases.py”,第 2093 行,在 print_figure **kwargs) 文件中“ C:\Python27\lib\site-packages\matplotlib\backends\backend_agg.py",第 483 行,在 print_raw 渲染器中。_renderer.write_rgba(filename_or_obj) RuntimeError: Error writing to file
  • 请发表您最后的评论作为答案并接受它。

标签: python animation matplotlib ffmpeg scatter


【解决方案1】:

抱歉耽搁了。我找到了一种解决方法,只需保存大量单独的图像,然后调用 ffmpeg 将它们链接在一起。这并不理想,但可以完成工作。 (大班的一部分)

def easyway(self, frames):
    ##INSERT CODE TO GET xdata and ydata!
    for i in range(0, frames):
       fileName = "videoName"+"%04d.png" % i
       matplotlib.pyplot.scatter(xdata,ydata,c=coldata, marker='*',
                              s=15.0, edgecolor='none')
       matplotlib.pyplot.savefig(self.workingDirectory+'temp/'+fileName, dpi=dpi)
       matplotlib.pyplot.close()   
       ##INSERT CODE TO UPDATE xdata and ydata!
    self.createVideoFile(fps)#calls FFMpeg to chain together all the pictures

    if cleanUp:#removes all the picture files created in the process
        print "temporary picture files being removed..."
        self.clearDirectory()
    print "FINISHED"

def clearDirectory(self,directoryName='temp'):
    files = glob.glob(self.workingDirectory+directoryName+"/*")
    for f in files:
        os.remove(f)

def createVideoFile(self,fps=3):
    command="ffmpeg -f image2 -r %s -i %s%s" % (str(fps), self.workingDirectory+'temp/', self.universe.description)
    command+="%04d.png"
    command+=" -c:v libx264 -r 30 %s.mp4" % (self.workingDirectory+'videos/'+self.universe.description)
    print "Running command:"
    print command
    p = subprocess.Popen(command, shell=True, stdout = subprocess.PIPE, stderr=subprocess.STDOUT)
    output = p.communicate()[0]
    print "output\n"+"*"*10+"\n"
    print output
    print "*"*10
    print "Video file has been written"

【讨论】:

    猜你喜欢
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-05
    • 2016-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多