用Python Matplotlib 制做动画

前言python

本文的文字及图片来源于网络,仅供学习、交流使用,不具备任何商业用途,版权归原做者全部,若有问题请及时联系咱们以做处理。算法

做者:Hanz编程

 

— 1 —网络

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

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

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

 

 

这篇文章的重点仍是主要放在 python 中如何用 Matploylib 制做动画。学习

但若是你不太熟悉模拟游戏的话(它更像是能够看的模拟动画,而非能够玩的游戏),我来给你们介绍一下规则:动画

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

 

— 2 —ui

创建网格

咱们首先导入所需的库。

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。生成的图片长这样:

 

如今咱们须要写一个能够给 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)

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

 

 

— 4 —

总结

但愿这篇文章能帮到你们。在结束以前,让我来帮助你们脑补更多咱们今天学到的动画功能在数据科学上的应用:

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