如何基于Python Matplotlib实现网格动画


Posted in Python onJuly 20, 2020

—1—

如果你对本文的代码感兴趣,可以去 Github (文末提供)里查看。第一次运行的时候会报一个错误(还没找到解决办法),不过只要再运行一次就正常了。

这篇文章虽然不是篇典型的数据科学类文章,不过它涉及到数据科学以及商业智能的应用。Python 的 Matplotlib 是最常用的图表绘制以及数据可视化库。我们对折线图、柱状图以及热力图都比较熟悉,但你知道用 Matplotlib 还能做简单的动画吗?

下面就是用 Matplotlib 制作动画的例子。展示的是 John Conway 的 《The Game of Life》,这是一个 Metis(数据科学夏令营)中的编程挑战题目,同时给了我一个机会来制作我的第一个 Python 动画。看看结果的动图:

如何基于Python Matplotlib实现网格动画

这篇文章的重点还是主要放在 python 中如何用 Matploylib 制作动画。

但如果你不太熟悉模拟游戏的话(它更像是可以看的模拟动画,而非可以玩的游戏),我来给大家介绍一下规则:

  • 一开始先设置一个 N×N 的网格(我的动画中用的是 50×50 );
  • 接着随机地向格子中填充“小细胞”(一开始随机地从 2500 个格子中选取 1500 个进行填充);
  • 如果邻居小细胞少于等于 1 个,那格子中的小细胞会死掉;
  • 如果邻居大于等于 4 个的也会死掉;
  • 只有 2 个或 3 个邻居时可以生存;
  • 空的格子中如果正好有 3 个邻居,则会长出 1 个新的“小细胞”;

—2—

建立网格

我们首先导入所需的库。

import time
from IPython import display
import matplotlib.pyplot as plt
import matplotlib.animation as animation

我们会利用Matploylib 动画模块中的 FuncAnimation() 函数。 FuncAnimation()是通过多次调用一个函数并逐次更新图片来实现让图片动起来的。我们来一步步地实现这个过程。

但首先,我们需要先初始化我们的网格。下面的几行代码用来存储我们输入的数据:

  • 我们需要一个 50×50 大小的网格;
  • pad 变量可以使得计算邻居变得更容易。通过在边界外添加一层空白格子,我们就不需要额外再写一个逻辑来处理网格的边界。因此我们 50×50 的网格其实是被一圈空白格子包围着,这使得实际的 numpy 序列的大小为 52×52;
  • initial_cels 变量表示在网格启动的时候我们想要多少“小细胞”。他们会被随机地分布在网格上。
# Input variables for the board
boardsize = 50    # board will be X by X where X = boardsize
pad = 2        # padded border, do not change this!
initial_cells = 1500 # this number of initial cells will be placed
           # in randomly generated positions

接下来我们随机地生成一系列“小细胞”的初始坐标(上面我们选择了 1500 个)。把这些坐标存储在 pos_list 变量中。

# Get a list of random coordinates so that we can initialize
# board with randomly placed organisms
pos_list = []
for i in range(initial_cells):
  pos_list.append([random.randint(1, boardsize),
           random.randint(1, boardsize)])

然后我们是时候该初始化网格了。我们会用一组叫 my_board 的 numpy 序列来代表我们的网格——我们先生成一个 52×52 数值为 0 的矩阵序列作为开始(比 50×50 大是由于增加了空白边缘),然后调用 init_board() 函数来根据 pos_list 中的坐标把“小细胞”填充到网格中。辅助函数的具体细节我不再展开讲了,不过我把他们都整理到我的 Github 上了。

# Initialize the board
my_board = np.zeros((boardsize+pad, boardsize+pad))
my_board = init_board(pos_list, my_board)

—3—

制作网格动画

这是我们最期待的部分——动画!首先,我们需要完善一些配置。下面的几行代码用来生成展示我们动画的 mtplotlib 图框。

# Required line for plotting the animation
%matplotlib notebook
# Initialize the plot of the board that will be used for animation
fig = plt.gcf()

接下来制作我们的第一帧。 mtplotlib 中的 imshow() 函数可以接收一组 numpy 矩阵然后返回一张图片。很酷吧!

# Show first image - which is the initial board
im = plt.imshow(my_board)
plt.show()

传入 imshow() 的变量是我们的初始的网格 my_board。生成的图片长这样:

如何基于Python Matplotlib实现网格动画

现在我们需要写一个可以给 FuncAnimation() 调用的辅助函数。 animate() 函数接受一帧画面作为输入充当计数器。这个画面计数器就是 FuncAnimation() 和 animate() 函数沟通的桥梁——在每一个时间点(也就是每一帧),它都会调用一次 animate()。然后 animate() 会逐次使用辅助函数 update_board() 来对网格进行迭代。最后, set_data() 函数将图片更新为迭代后的网格,这就完成了。

# Helper function that updates the board and returns a new image of
# the updated board animate is the function that FuncAnimation calls
def animate(frame):
  im.set_data(update_board(my_board))
  return im,

一切顺利!我们准备调用 FuncAnimation() 函数了。注意输入的参数:

  • fig 是我们在前面创建的用来装载我们的动画的图形变量;
  • animate 是 FuncAnimation() 用画面计数器进行沟通的函数(自动传入,不需要特别声明)
  • frames 表示我们希望动画持续多少帧,在这里我们想要动画的长度为 200 帧;
  • interval 表示每一帧之间间隔的毫秒数。我们想要每帧之间间隔 50 毫秒。
# This line creates the animation
anim = animation.FuncAnimation(fig, animate, frames=200,
                interval=50)

就这么简单!不是很难吧?为了庆祝我们成功制作动画,我再送大家一个动画:

如何基于Python Matplotlib实现网格动画

—4—

总结

希望这篇文章能帮到大家。在结束之前,让我来帮助大家脑补更多我们今天学到的动画功能在数据科学上的应用:

  • 一个个地画出蒙特卡洛模拟数据,你能观察到最终的分布是如何逐步形成的;
  • 按顺序遍历时间序列数据,可以描绘你的模型或数据在新的观察角度下有什么表现;
  • 当你改变输入参数时,比如族群数,可以展现你的算法是如何划分族群的;
  • 根据时间或不同的数据子集生成关联热力图,用于观察不同的样本是如何影响你的模型的预期参数的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
忘记ftp密码使用python ftplib库暴力破解密码的方法示例
Jan 22 Python
Python素数检测实例分析
Jun 15 Python
Python实现LRU算法的2种方法
Jun 24 Python
Django查找网站项目根目录和对正则表达式的支持
Jul 15 Python
基python实现多线程网页爬虫
Sep 06 Python
python字典键值对的添加和遍历方法
Sep 11 Python
python如何获取当前文件夹下所有文件名详解
Jan 25 Python
django数据关系一对多、多对多模型、自关联的建立
Jul 24 Python
pytorch GAN伪造手写体mnist数据集方式
Jan 10 Python
python中threading开启关闭线程操作
May 02 Python
python 多线程爬取壁纸网站的示例
Feb 20 Python
用gpu训练好的神经网络,用tensorflow-cpu跑出错的原因及解决方案
Mar 03 Python
Python常用数据分析模块原理解析
Jul 20 #Python
Python+Kepler.gl实现时间轮播地图过程解析
Jul 20 #Python
用pandas划分数据集实现训练集和测试集
Jul 20 #Python
Python数据可视化实现漏斗图过程图解
Jul 20 #Python
浅谈pandas dataframe对除数是零的处理
Jul 20 #Python
为什么说python更适合树莓派编程
Jul 20 #Python
Python faker生成器生成虚拟数据代码实例
Jul 20 #Python
You might like
php和jquery实现地图区域数据统计展示数据示例
2014/02/12 PHP
Thinkphp的volist标签嵌套循环使用教程
2014/07/08 PHP
深入浅析php中sprintf与printf函数的用法及区别
2016/01/08 PHP
php使用SAE原生Mail类实现各种类型邮件发送的方法
2016/10/10 PHP
php 三元运算符实例详细介绍
2016/12/15 PHP
PHP图像处理技术实例总结【绘图、水印、验证码、图像压缩】
2018/12/08 PHP
PHP字符串中抽取子串操作实例分析
2019/06/22 PHP
Laravel框架创建路由的方法详解
2019/09/04 PHP
关于laravel 日志写入失败问题汇总
2019/10/17 PHP
js变量以及其作用域详解
2020/07/18 Javascript
一个JQuery操作Table的代码分享
2012/03/30 Javascript
javascript 构造函数强制调用经验总结
2012/12/02 Javascript
轻松创建nodejs服务器(10):处理上传图片
2014/12/18 NodeJs
Javascript的表单验证-初识正则表达式
2016/03/18 Javascript
即将发布的jQuery 3 有哪些新特性
2016/04/14 Javascript
jQuery实现div横向拖拽排序的简单实例
2016/07/13 Javascript
AngularJS入门教程之数据绑定用法示例
2016/11/01 Javascript
JS创建Tag标签的方法详解
2017/06/09 Javascript
详解webpack 多页面/入口支持&公共组件单独打包
2017/06/29 Javascript
nodejs动态创建二维码的方法
2017/08/12 NodeJs
Mongoose中document与object的区别示例详解
2017/09/18 Javascript
微信小程序实现二维码签到考勤系统
2020/01/16 Javascript
JavaScript Window浏览器对象模型原理解析
2020/05/30 Javascript
Python中的文件和目录操作实现代码
2011/03/13 Python
Python入门篇之正则表达式
2014/10/20 Python
Python中在脚本中引用其他文件函数的实现方法
2016/06/23 Python
Python正则表达式非贪婪、多行匹配功能示例
2017/08/08 Python
python中的tcp示例详解
2018/12/09 Python
解决运行django程序出错问题 'str'object has no attribute'_meta'
2020/07/15 Python
viagogo英国票务平台:演唱会、体育比赛、戏剧门票
2017/03/24 全球购物
中国一家专注拼团的社交购物网站:拼多多
2018/06/13 全球购物
毕业生机械建模求职信
2013/10/14 职场文书
教师师德教育的自我评价
2013/10/31 职场文书
婚庆司仪主持词
2014/03/15 职场文书
2015年幼儿园班主任工作总结
2015/05/12 职场文书
Python自动操作神器PyAutoGUI的使用教程
2022/06/16 Python