翻译:疯狂的技术宅
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')
动画有助于突出显示没法经过静态图表轻松传达的某些功能。尽管如此,没必要要的过分使用有时会使事情复杂化,应该明智地使用数据可视化中的每一个功能以产生最佳效果。
更多文章请关注微信公众号:硬核智能