用Python和MoviePy将数据动态可视化

Python有些出色的数据可视化库,但很少能渲染GIF或视频动画。本文介绍如何运用MoviePy作为其他库的通用动画插件。

有了 MoviePy ,你可以用一个函数 make_frame(t) 自定义动画,并返回相应的时间t的视频帧(秒):

在之前的文章中,我用这种方法来做制作矢量图形动画(用Gizeh库),和光线追踪三维场景(由POV-Ray做出)。这篇文章包括 MayaVi、vispy、matplotlib、NumPy 和 Scikit-image 这些科学库。

用Mayavi的动画

Mayavi是一个针对有简单接口的交互3D数据可视化的Python模块。在第一个例子中,我们做一个高度随时间t变化的表面的动画:

另一个例子是一个坐标和观看角度都随时间变化的线框网:

因为Mayavi有着强大的ITK可视化引擎,它还可以处理复杂数据集。这里有一个源自于Mayavi例子的动画

代码

Animations with Vispy 用Vispy的动画

Vispy是另一个以OpenGL为基础的交互3D可视化库。至于Mayavi,我们用MoviePy先做出一个图和一个网。

还有一些更高级的例子(源自于Vispy库),它是用C代码片段中嵌入Python代码,微调了3D渲染的:

代码

代码

用Matplotlib的动画

2D/3D绘图库Matplotlib已经有了动画模块,但我发现moviepy可以做出更轻量级,质量更好的视频,却达到了两倍的速度(不知道为什么?在这里看到更多细节)。这里有个如何使用matplotlib和moviepy的例子:

Matplotlib有很多漂亮的主题,而且和像Pandas或Scikit-Learn这些数字模块能很好配合。让我们看一个SVM分类器,以更好地明白训练点的数量增加时的地图。

简单明了,背景色代表分类器辨识黑点和白点属于哪里。在一开始没有真正的线索,但随着更多的点出钱,月牙形分布区域渐渐显现了。

用Numpy的动画

如果你正用着Numpy数组(Numpy是一个Python的中央数字库),你不需要任何外部绘图库,你可以直接将这些数组馈入MoviePy。

这通过模拟在法国的僵尸爆发(灵感来自Max Berggren的博客,伯乐在线已有全文翻译:《用Python在地图上模拟疫情扩散》)。法国被仿作一个所有分散和感染的计算都完成的网格(NumPy数组)。每隔一段时间,一些NumPy操作变换网格为有效的RGB图像,并将其发送到Moviepy。

代码

把动画放到一起

什么比一个动画更好呢?两个动画!你可以利用MoviePy视频合成功能,来混合来自不同库的动画:

Or for something more artistic:

也许有点太快了,但有时你必须给你的观众一些可以让他们议论的东西。

你也可以注解动画,当比较不同的过滤器或算法时,注解动画很实用。让我们看看四张由库scikit-image变换的图像:


如果我们把CompositeVideoClip和clips_array替代成concatenate_videoclips,我们得到标题效果式动画:

最终,处理视频数据时,MoviePy会非常好用,因为这是它的首要任务。最后一个例子,我们通过视频帧阈值和白色像素计数,估计一个细菌种群大小。第三面板显示,人口规模呈指数增长的时间。

代码

一个库就可以做所有动画了?

我希望给了你足够的例子,来提升你的同事对你下次展示中的印象。总之要他的输出能被转换成Numpy数组,其他的库也能用MoviePy来做动画。

一些库有自己的动画模块,但是修复和维护很痛苦!感谢那些在不同背景下测试MoviePy的人们,它变得更稳定了(除非没人再报bug),而且可以适用于各种环境。MoviePy  仍有很多要去做的,但如果作者开始依靠它来做视频和GIF渲染,像Pandas和scikit-Learn依赖matplotlib做绘制,那会很好。

为了本文的完整性,同时也为了更好地满足您的需要,我必须提到的ImageIO,这是另一个可以编写视频的Python库,它专注于提供一个非常简单的接口来读取或写入任何图像,视频或容积数据。比如你用imwrite()写图像,用mimwrite()写视频/ GIF,用volwrite()写体积数据,或只是write()写流数据。

谢谢大家,GIF万岁!

1 14 收藏 3 评论

关于作者:yottatiana

新浪微博:@丹川黑马 个人主页 · 我的文章 · 11

相关文章

可能感兴趣的话题



直接登录
最新评论
跳到底部
返回顶部