在实际应用中,我们经常有这样的需求,希望观察到数据的变化过程而不仅仅是最终的结果,例如股票的实时变化、各国家疫情人数动态变化等。此时,传统的静态图无法满足我们的需求,这就需要借助于动态效果图了。在Matplotlib中为我们提供了绘制动态图效果的相关类库,今天我们就一起来学习如何使用Matplotlib绘制动态效果图。首先给出几个案例效果。
在Matplotlib库中有一个子库animation,该库下定义了多种用于绘制动态效果图的类,例如FuncAnimation,ArtistAnimation等,我们这里主要介绍FuncAnimation的使用。该类通过重复调用某个功能函数从而实现动态绘图效果,在功能函数中会对图进行一些修改,只要调用时间间隔足够短,给人的感觉就是图在动态变化。创建FuncAnimation对象时,需要传递的主要参数及其含义如下:
注意事项:
案例一:显示正弦曲线绘制过程
完整代码参考:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
fig = plt.figure(figsize=(10, 5)) # 创建图
plt.rcParams["font.family"] = "FangSong" # 支持中文显示
plt.ylim(-12, 12) # Y轴取值范围
plt.yticks([-12 + 2 * i for i in range(13)], [-12 + 2 * i for i in range(13)]) # Y轴刻度
plt.xlim(0, 2 * np.pi) # X轴取值范围
plt.xticks([0.5 * i for i in range(14)], [0.5 * i for i in range(14)]) # X轴刻度
plt.title("函数 y = 10 * sin(x) 在[0,2Π]区间的曲线") # 标题
plt.xlabel("X轴") # X轴标签
plt.ylabel("Y轴") # Y轴标签
x, y = [], [] # 用于保存绘图数据,最开始时什么都没有,默认为空
def update(n): # 更新函数
x.append(n) # 添加X轴坐标
y.append(10 * np.sin(n)) # 添加Y轴坐标
plt.plot(x, y, "r--") # 绘制折线图
ani = FuncAnimation(fig, update, frames=np.arange(0, 2 * np.pi, 0.1), interval=50, blit=False, repeat=False) # 创建动画效果
plt.show() # 显示图片
这里为了可以观察到整体效果,设置了X轴和Y轴的取值范围,如果不设置取值范围,程序会根据绘图的数据自动调整X轴和Y轴的取值范围,就看不到曲线绘制的过程。
这里的功能函数名为update,这个函数名可以任意命名。在该函数中,只是将新的数据添加在原有数据中,然后重新绘制效果图,因此图上的数据会慢慢变多,直到结束为止。
这里frames参数是一个可迭代对象,程序执行时,会依次取出该对象中的元素,然后传递给update函数。
案例二:显示动态变化的正弦和余弦曲线
图中包含两条曲线,一个正弦曲线一个余弦曲线,这两条曲线在水平移动。
完整代码参考:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots() # 创建画布和绘图区
ax.set_axis_off() # 不显示坐标轴
x = np.arange(0, 2 * np.pi, 0.01) # 生成X轴坐标序列
line1, = ax.plot(x, np.sin(x)) # 获取折线图对象,逗号不可少,如果没有逗号,得到的是元组
line2, = ax.plot(x, np.cos(x)) # 获取折线图对象,逗号不可少
def update(n): # 动态更新函数
line1.set_ydata(np.sin(x + n / 10.0)) # 改变线条y的坐标值
line2.set_ydata(np.cos(x + n / 10.0)) # 改变线条y的坐标值
ani = FuncAnimation(fig, update, frames=100, interval=50, blit=False, repeat=False) # 创建动画效果
plt.show() # 显示图
这里frames参数是一个整数100,此时,程序会自动生成一个range(100)的可迭代对象,然后依次取出每一个数,将其传递给update函数。
案例三:编程语言排行榜随时间动态变化效果
编程语言排行榜相关数据的爬取可参考我的另一篇博文:Python爬虫与数据可视化案例(共享源码)
主要思路:依次获取每个月各编程语言的占比,然后按照从大到小对其排序,最后绘制水平条形图,显示占比数据。
完整代码参考:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def draw(item):
plt.cla() # 清空原有内容
date = item[0] # 获取日期
data = item[1] # 获取该日期下各编程语言占比
temp_index = np.argsort(data["value"]) # 从大到小排序,获取排序后的索引
values = data["value"].values[temp_index] # 排序后的值
names = data["name"].values[temp_index] # 排序后的名称
colors = ["r", "b", "y", "c", "g", "m", "pink", "purple", "gray", "orange"] # 定义颜色列表
# 绘制水平条形图
plt.barh(range(1, len(values) + 1), values, color=colors)
plt.yticks(range(1, len(values) + 1), names) # Y轴标签
plt.xlim(0, max(values) + 2) # X轴取值范围,在最大值基础上加2,从而有足够空间显示数据
plt.title("编程语言排行榜--{}".format(date), fontsize=20) # 标题,显示日期
for x in range(1, len(values) + 1): # 在图中显示各编程语言的占比
plt.text(values[x - 1] + 0.1, x - 0.1, str(values[x - 1]) + "%", fontsize=14)
datas = pd.read_csv("lang.csv") # 读取数据
temp = datas.groupby("date") # 按照日期进行分组
fig = plt.figure(figsize=(12, 6)) # 创建图
plt.rcParams["font.family"] = "FangSong" # 支持中文显示
ani = FuncAnimation(fig, draw, frames=temp, interval=50, blit=False, repeat=False) # 创建动画效果
plt.show() # 显示图片
源代码及相关资源,可关注 Python资源分享 微信公众号,回复 动态图 即可获取。