用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 —

總結

但願這篇文章能幫到你們。在結束以前,讓我來幫助你們腦補更多咱們今天學到的動畫功能在數據科學上的應用:

  • 一個個地畫出蒙特卡洛模擬數據,你能觀察到最終的分佈是如何逐步造成的;
  • 按順序遍歷時間序列數據,能夠描繪你的模型或數據在新的觀察角度下有什麼表現;
  • 當你改變輸入參數時,好比族羣數,能夠展示你的算法是如何劃分族羣的;
  • 根據時間或不一樣的數據子集生成關聯熱力圖,用於觀察不一樣的樣本是如何影響你的模型的預期參數的。
相關文章
相關標籤/搜索