如何让你的 Python 图表动起来?
当今世界越来越需要数据。公司和个人可以使用它通过机器学习来预测股票价格、跟踪运动员的健康状况、研究某个城市的房价……可能性是无穷无尽的。
虽然原始数据是分析的基础,但它可以讲述的故事更为重要。讲述这个故事是工程师和数据科学家的工作。而视觉效果可能是数据传达想法的最佳方式之一。
想一想,你宁愿看一行又一行的数据还是几个总结它的图?像大多数人一样,你多半也觉得图表听起来更好。虽然并非总是必要的,但在图表中添加动画还可以为你的讲述提供更多的意义。
阅读完本文后,你应该就能自己创建出上面的图表,并使用框架创建属于自己的精美动画。
对于本文,我会假设你对如何用Python执行基本的数据操作和绘图有一点背景知识。请记住,这不是使用 Python 动画功能的唯一方法,如果你有其他想法,欢迎在文章下面分享!如果你想了解更多数据分析相关内容,可以阅读以下这些文章:
数据清理必备的Python Packages
Data Scientist生产力进阶—Python OOP编程快速入门
通过案例数据集,带你了解Python数据分析和数据可视化
10个Python函数,帮你解决70%的数据分析问题
我们将使用三维线和散点来创建轨迹,但这些概念还可以扩展到其他绘图类型,例如二维线、条形图、饼图、等高线等。
导入库
Python 有大量用于数据分析的库,我们将使用其中的几个。让我们启动一个新的脚本,并为项目导入我们所需的包:
# Importing Packages
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import animation
- NumPy库用来创建数值数组和使用三角函数(定义为np以便于调用)
- Matplotlib中的Pyplot将用于绘制图形(定义为plt以便于调用)
- Axes3D将用于为我们的绘图创建三维轴
- 来自Matplotlib的animation将用于通过重复调用我们的函数来创建动画
创建数据集
在绘制图表前,我们首先要创建要绘制的数据。对于这一部分,我用 sine 函数和一个从0到20的时间数组创建了一些位置数据(在动画中我把它标记为秒)。
# Time Array
t = np.linspace(0, 20, 100)
# Position Arrays
x = np.sin(np.pi/5 * t)
y = np.sin(np.pi/3 * t)
z = np.linspace(0, 100, 100)
# Setting up Data Set for Animation
dataSet = np.array([x, y, z]) # Combining our position coordinates
numDataPoints = len(t)
你也可以改动上面的时间和位置数组来创建新的轨迹。我们接下来要用 dataSet和numDataPoints变量定义动画函数。
动画功能
为了使我们的图形动画化,我们将用animation类中的一个名为FuncAnimation的函数。你可以在此处访问关于这两个的文档:
https://matplotlib.org/stable/api/animation_api.html
FuncAnimation要求我们创建自己的函数来更新线、点等,在这里我们将其定义为animate_func 。
def animate_func(num):
ax.clear() # Clears the figure to update the line, point,
# title, and axes # Updating Trajectory Line (num+1 due to Python indexing)
ax.plot3D(dataSet[0, :num+1], dataSet[1, :num+1],
dataSet[2, :num+1], c='blue') # Updating Point Location
ax.scatter(dataSet[0, num], dataSet[1, num], dataSet[2, num],
c='blue', marker='o') # Adding Constant Origin
ax.plot3D(dataSet[0, 0], dataSet[1, 0], dataSet[2, 0],
c='black', marker='o') # Setting Axes Limits
ax.set_xlim3d([-1, 1])
ax.set_ylim3d([-1, 1])
ax.set_zlim3d([0, 100])
# Adding Figure Labels
ax.set_title('Trajectory \nTime = ' + str(np.round(t[num],
decimals=2)) + ' sec')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
首先要注意传递给animate_func的num变量。这是当前动画步骤的索引。当我们将animate_func传递给FuncAnimation时,它会迭代我们的num变量。我们可以使用该变量来迭代所有我们之前创建的数据集。
这个函数从清除图形开始。这将删除线、点、原点、轴标签和标题。然后它添加更新的轨迹线(从0到num )和点位置(在步骤num处)。我们的原点在此图中保持不变,因此你会注意到num没有显示,因为我们没有更改原点。接下来,该函数定义我们不变的轴限制(unchanging axis limits)。如果你希望轴随着数字的增加而改变(使轴变为动态),那么你可以删除轴限制。
最后,该函数定义了我们的标题和轴标签。标签很简单,只有我们的x 、 y和z用于坐标。作为一点额外功能,我们有一个动态标题,显示轨迹的时间数组t。我们显示它(四舍五入到小数点后第二位),并在每次迭代时更新它。请注意,这些不是实时的秒数。
绘制我们的动画
最后一步是使用FuncAnimation绘制我们的动画。我们首先创建具有三维轴的图形对象。然后我们使用FuncAnimation ,它将图形、我们之前创建的动画函数、间隔值(interval value)和帧值(frames)作为输入。间隔是以毫秒为单位的帧之间的延迟,帧是你想显示的帧数。最后两个是可选参数,但如果你想调整动画的外观,就需要包含它们。
# Plotting the Animation
fig = plt.figure()
ax = plt.axes(projection='3d')
line_ani = animation.FuncAnimation(fig, animate_func, interval=100,
frames=numDataPoints)
plt.show()
现在,你可以运行代码了,如果正确完成,你的绘图应如下所示(点的速度可能不同):
保存我们的动画
如果想把动画保存为.gif文件,你可以用以下代码来完成。
# Saving the Animation
f = r"c://Users/(Insert User)/Desktop/animate_func.gif"
writergif = animation.PillowWriter(fps=numDataPoints/6)
line_ani.save(f, writer=writergif)
你需要选择一个位置来保存它,并将其存储为f变量。你可以在PillowWriter中调整每秒帧数fps变量。我将numDataPoints变量(FuncAnimation中的帧数)除以6 ,使动画长度为6秒。
这就是本文的全部内容。感谢你的阅读!如果不想错过更多 Python 和数据分析文章,请关注我们的公众号!你还可以订阅我们的YouTube频道,观看大量数据科学相关公开课:https://www.youtube.com/channel/UCa8NLpvi70mHVsW4J_x9OeQ;在LinkedIn上关注我们,扩展你的人际网络!https://www.linkedin.com/company/dataapplab/
原文作者:Zack Fizell
翻译作者:Jiawei Tong
美工编辑:过儿
校对审稿:Jiawei Tong
原文链接:https://towardsdatascience.com/how-to-animate-plots-in-python-2512327c8263