Matplotlib: matplotlib 是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地行制图。而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中。
animation: animation中的animation.FuncAnimation(fig, animate, frames, interval)方法能为我们绘制动画
### 实现原理:
* 实现排序算法的可视化,只要将每一次数据的变化进行颜色标记,将其作为一帧柱状图画面的数据绘制出来,将上一帧的画面清除,循环往复直到最终排好序的画面展示,我们的一次排序算法可视化的循环就可以完成了。 * 我们便需要一个二维列表(frames),里面的元素是每一帧的数据列表 * 也需要将每个数据变成一个class,有自己的value属性和color属性,以及set_color()方法
### 导入相关库:
%matplotlib notebook import copy import random import matplotlib.pyplot as plt from matplotlib import animation
### 定义数据类,每个类中有自己的vaule与color、以及set_color的方法
class Data: def __init__(self, value): self.value = value self.color = '#6495ED' def set_color(self, color): self.color = color
### 冒泡算法方法
def sort(li): # 这样赋值的frames列表中的元素是一个个的列表,每一帧的数据是其中的元素 frames = [li] ds = copy.deepcopy(li) # 赋值一份初始列表,用于存储每一帧变化后的数据 # 冒泡排序: for i in range(32): for j in range(32 - i - 1): ds_r = copy.deepcopy(ds) # 赋值一份ds中的数据 ds_r[j].set_color('#DC143C') # 将数据的color设置为'#DC143C' ds_r[j + 1].set_color('#7FFFAA') frames.append(ds_r) # 将color变化后的数据追加到frmaes中 if ds[j].value > ds[j + 1].value: ds[j + 1], ds[j] = ds[j], ds[j + 1] frames.append(ds) # 将最后排好序的数据追加 return frames
### 处理数据
li = list(range(1, 33)) # 生成1~32 random.shuffle(li) # 打乱顺序 data_set = [Data(d) for d in li] # 将列表中的每一个数值变成Data类的对象 frames = sort(data_set) # 进行排序
fig = plt.figure() # 绘制画布
def animate(fi): ax = plt.gca() ax.cla() bar = ax.bar( list(range(32)), # x [d.value for d in frames[fi]], # data 0.9, # width color=[d.color for d in frames[fi]] ) plt.xticks([]) plt.yticks([]) return bar
animate(): 是用于处理动画每一帧变化内容的函数,可以接受参数,其接受的参数是从animation.FuncAnimation()中的frames获得,frames参数会将0到len(frames) 的变量一一传入,这样frames[fi]就可以遍历二维列表中的每一个列表(即遍历每一帧的数据)
ax = plt.gca(): 获取当前画布上的子图
ax.cla(): 将子图清除
bar = ax.bar() 绘制柱状图
plt.xticks([])/plt.yticks([]): 使画布的x轴与y轴不显示
anim = animation.FuncAnimation(fig, animate, frames=len(frames), interval=100) #anim.save('selectsort.gif') plt.show()
animation.FuncAnimation()的参数: a).fig 绘制动图的画布名称
b).func自定义动画函数,即下边程序定义的函数update,即动画每一帧变化内容的函数
c).frames动画长度,一次循环包含的帧数,在函数运行时,其值会传递给函数update(n)的形参“n”,从0~n传递过去
d).init_func自定义开始帧,即传入刚定义的函数init,初始化函数,即最开始显示的画面
e).interval更新频率,以ms计
f).blit选择更新所有点,还是仅更新产生变化的点。应选择True,但mac用户请选择False,否则无法显示
plt.show(): 从名字上可以看出是用来干什么的,将动画画布显示出来
结果图: