翻譯:瘋狂的技術宅
https://towardsdatascience.co...
更多文章請關注微信公衆號:硬核智能html
動畫是一種展現現象的有趣方式。相對於靜態圖表,人類老是容易被動畫和交互式圖表所吸引。在描述多年來的股票價格、過去十年的氣候變化、季節性和趨勢等時間序列數據時,動畫更有意義,由於咱們能夠看到特定的參數是怎樣隨時間變化的。python
上面的圖是雨滴的模擬而且已經使用 Matplotlib 庫實現,該庫是一個廣爲人知的祖父級別的 python 可視化包。 Matplotlib 經過對 50 個散點的比例和透明度進行設置來模擬雨滴。今天,Python 擁有大量強大的可視化工具,如 Plotly、Bokeh、Altair等等。這些庫可以實現最早進的動畫和交互特性。儘管如此,本文的目的是強調這個庫的另外一個方面,這個方面沒有人進行過太多的探索,這就是動畫。git
Matplotlib 是一個廣受歡迎的 Python 2D 繪圖庫。不少人都是從 Matplotlib 開始數據可視化之旅的。可使用matplotlib輕鬆生成圖表、直方圖、功率譜,條形圖,錯誤圖表,散點圖等。它還與 Pandas 和 Seaborn 等庫無縫集成,創造出更加複雜的可視化效果。github
matplotlib 的優勢是:web
然而,也有一些方面 Matplotlib 落後於同類的庫。後端
這份複習資料是來自 Datacamp 的 Matplotlib 小抄,你能夠經過它來提升本身的基礎知識。api
Matplotlib 的 animation
基類負責處理動畫部分。它提供了一個構建動畫功能的框架。使用下面兩個接口來實現:微信
FuncAnimation
經過重複調用函數 func 來產生動畫。ArtistAnimation:
動畫使用一組固定的 Artist
對象。可是,在這兩個接口中,FuncAnimation 是最方便使用的。你能夠經過閱讀文檔 獲得的更多信息,由於咱們只關注 FuncAnimation
工具。app
numpy
和 matplotlib
。ffmpeg
或 imagemagick
。準備好以後,咱們就能夠在 Jupyter note 中開始建立第一個動畫了。能夠從 Github 獲得本文的代碼。框架
咱們先用 FuncAnimation
建立一個在屏幕上移動的正弦波的動畫。動畫的源代碼來自 Matplotlib 動畫教程。首先看一下輸出,而後咱們會分析代碼以瞭解幕後的原理。
import numpy as np from matplotlib import pyplot as plt from matplotlib.animation import FuncAnimation plt.style.use('seaborn-pastel') fig = plt.figure() ax = plt.axes(xlim=(0, 4), ylim=(-2, 2)) line, = ax.plot([], [], lw=3) def init(): line.set_data([], []) return line, def animate(i): x = np.linspace(0, 4, 1000) y = np.sin(2 * np.pi * (x - 0.01 * i)) line.set_data(x, y) return line, anim = FuncAnimation(fig, animate, init_func=init, frames=200, interval=20, blit=True) anim.save('sine_wave.gif', writer='imagemagick')
init
函數,它將使動畫開始。 init
函數對數據進行初始化並設置軸限制。blit
參數確保只重繪那些已經改變的圖塊。這是在 Matplotlib 中建立動畫的基本方法。經過對代碼進行一些調整,能夠建立有趣的可視化圖表。接下來看看更多的可視化案例。
一樣,在 GeeksforGeeks 中有一個很好的例子。如今讓咱們在 matplotlib 的 animation
類的幫助下建立一個緩慢展開的動圈。該代碼很是相似於正弦波圖,只需稍做調整便可。
import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np plt.style.use('dark_background') fig = plt.figure() ax = plt.axes(xlim=(-50, 50), ylim=(-50, 50)) line, = ax.plot([], [], lw=2) # initialization function def init(): # creating an empty plot/frame line.set_data([], []) return line, # lists to store x and y axis points xdata, ydata = [], [] # animation function def animate(i): # t is a parameter t = 0.1*i # x, y values to be plotted x = t*np.sin(t) y = t*np.cos(t) # appending new points to x, y axes points list xdata.append(x) ydata.append(y) line.set_data(xdata, ydata) return line, # setting a title for the plot plt.title('Creating a growing coil with matplotlib!') # hiding the axis details plt.axis('off') # call the animator anim = animation.FuncAnimation(fig, animate, init_func=init, frames=500, interval=20, blit=True) # save the animation as mp4 video file anim.save('coil.gif',writer='imagemagick')
在繪製動態數量(如庫存數據,傳感器數據或任何其餘時間相關數據)時,實時更新的圖表會派上用場。咱們繪製了一個簡單的圖表,當有更多數據被輸入系統時,該圖表會自動更新。下面讓咱們繪製一家假想公司在一個月內的股票價格。
# importing libraries import matplotlib.pyplot as plt import matplotlib.animation as animation fig = plt.figure() # creating a subplot ax1 = fig.add_subplot(1,1,1) def animate(i): data = open('stock.txt','r').read() lines = data.split('\n') xs = [] ys = [] for line in lines: x, y = line.split(',') # Delimiter is comma xs.append(float(x)) ys.append(float(y)) ax1.clear() ax1.plot(xs, ys) plt.xlabel('Date') plt.ylabel('Price') plt.title('Live graph with matplotlib') ani = animation.FuncAnimation(fig, animate, interval=1000) plt.show()
如今,打開終端並運行 python 腳本。你將獲得以下圖所示的圖表,該圖表會自動更新:
這裏的間隔是 1000 毫秒或一秒。
建立 3D 圖形是很常見的,但若是咱們想要爲這些圖形的視角設置動畫,該怎麼辦呢?咱們的想法是更改攝像機視圖,而後用每一個生成的圖像來建立動畫。在 Python Graph Gallery 上有一個很好的例子。
在與 jupyter notebook 相同的目錄中建立名爲 volcano 的文件夾。全部圖片文件都將存儲在這裏,而後將在動畫中使用。
# library from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt import pandas as pd import seaborn as sns # Get the data (csv file is hosted on the web) url = 'https://python-graph-gallery.com/wp-content/uploads/volcano.csv' data = pd.read_csv(url) # Transform it to a long format df=data.unstack().reset_index() df.columns=["X","Y","Z"] # And transform the old column name in something numeric df['X']=pd.Categorical(df['X']) df['X']=df['X'].cat.codes # We are going to do 20 plots, for 20 different angles for angle in range(70,210,2): # Make the plot fig = plt.figure() ax = fig.gca(projection='3d') ax.plot_trisurf(df['Y'], df['X'], df['Z'], cmap=plt.cm.viridis, linewidth=0.2) ax.view_init(30,angle) filename='Volcano/Volcano_step'+str(angle)+'.png' plt.savefig(filename, dpi=96) plt.gca()
這將會在 Volcano 文件夾中建立多個 PNG 文件。如今用 ImageMagick 將它們轉換爲動畫。打開終端並切換到 Volcano 目錄下輸入如下命令:
convert -delay 10 Volcano*.png animated_volcano.gif
Celluloid 是一個Python模塊,它簡化了在 matplotlib 中建立動畫的過程。這個庫建立一個 matplotlib 圖,並從中再建立一個 Camera
。而後從新處理數據,並在建立每一個幀後,用 camera 拍攝快照。最後建立包含全部幀的動畫。
pip install celluloid
如下是使用 Celluloid 模塊的一些示例。
from matplotlib import pyplot as plt from celluloid import Camera fig = plt.figure() camera = Camera(fig) for i in range(10): plt.plot([i] * 10) camera.snap() animation = camera.animate() animation.save('celluloid_minimal.gif', writer = 'imagemagick')
import numpy as np from matplotlib import pyplot as plt from celluloid import Camera fig, axes = plt.subplots(2) camera = Camera(fig) t = np.linspace(0, 2 * np.pi, 128, endpoint=False) for i in t: axes[0].plot(t, np.sin(t + i), color='blue') axes[1].plot(t, np.sin(t - i), color='blue') camera.snap() animation = camera.animate() animation.save('celluloid_subplots.gif', writer = 'imagemagick')
import matplotlib from matplotlib import pyplot as plt from celluloid import Camera fig = plt.figure() camera = Camera(fig) for i in range(20): t = plt.plot(range(i, i + 5)) plt.legend(t, [f'line {i}']) camera.snap() animation = camera.animate() animation.save('celluloid_legends.gif', writer = 'imagemagick')
動畫有助於突出顯示沒法經過靜態圖表輕鬆傳達的某些功能。儘管如此,沒必要要的過分使用有時會使事情複雜化,應該明智地使用數據可視化中的每一個功能以產生最佳效果。
更多文章請關注微信公衆號:硬核智能