前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于python排序算法可视化二

关于python排序算法可视化二

作者头像
python与大数据分析
发布2022-03-11 14:00:03
5030
发布2022-03-11 14:00:03
举报
文章被收录于专栏:python与大数据分析

关于排序算法可视化只是简单在原来代码后追加了十几行代码,排序算法的可视化重要的是matplotlib.animation.FuncAnimation函数,该函数有几个重要的参数,一个是图表面板,一个是动画播放回调函数,一个数据帧,一个是初始化函数。

关键在于数据帧这一块,一种办法是生成所有待播放的数据,形成数据数组,然后在动画播放回调函数中进行播放,另外一种办法是使用数据迭代器,一边生成数据,一边交给回到函数进行播放。第一种容易理解一些,第二种函数和数据解耦不大容易。

可视化的另一个问题是对于matplotlib各种组件的对象和方法要熟悉,本文只是简单做一下尝试。

代码示例

代码语言:javascript
复制
import random
import copy
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

def init_sortdata(datarage=10,datanum=10):
    data = list(range(1,datarage+1))
    data = random.sample(data, k=datanum)
    return data

#计算时间函数
def print_run_time(func):
    def wrapper(*args, **kw):
        start_time = time.time()  # 程序开始时间
        ret=func(*args, **kw)     # 将被装饰函数的返回值接收
        end_time = time.time()   # 程序结束时间
        total_time = int(1000*(end_time - start_time)) #程序执行时间,毫秒计
        print('{}排序算法共计执行{}豪秒,开始时间为{},结束时间为{}'.format(func.__name__,total_time,start_time,end_time))
        return ret                # 返回被装饰函数的返回值
    return wrapper

class SortClass:
    def __init__(self,collection):
        self.collection=collection

    def swapAndDraw(self,tempbar, x1, x2):
        #tempbar 为 <BarContainer object of X artists>
        #tempbar[x1] 为 Rectangle(xy=(9.6, 0), width=0.8, height=98, angle=0) 对象
        temp1height = tempbar[x1].get_height()              #获取待交换图像x1的高度,写入临时变量
        tempbar[x1].set_height(tempbar[x2].get_height())    #将x1的高度置为x2的高度
        tempbar[x2].set_height(temp1height)                 #将x2的高度置为x1的高度
        tempbar[x2].set_fc("red")                           #将要交换的x2置为红色标志
        plt.draw()                                          #绘制图形
        plt.pause(0.1)                                      #为体现动画,设置延迟时间为0.1秒
        tempbar[x2].set_fc("green")                         #再将要交换的x2重置为绿色标志

    @print_run_time
    def bubble_sort(self):
        #冒泡排序,数据来自类的初始化,为了不改变源list数据,采用深拷贝方式
        dataset = copy.deepcopy(self.collection)
        stepdata=[]
        length = len(dataset)   #list长度
        runtimes=0              #交换次数
        looptimes=0             #循环次数
        print('原始数据=',dataset)  #记录原始数据
        plt.figure('bubble_sort')
        plt.title('bubble_sort')
        plt.xticks(range(0,length), rotation=45)                #进行X轴设置
        tempbar = plt.bar(range(length), dataset, fc="green")   #初始化元数据
        for i in range(length - 1):
            print(' 第{}轮外轮,开始数据={}'.format(i, dataset))
            swapped = False
            for j in range(length - 1 - i):
                if dataset[j] > dataset[j + 1]:                             #相邻元素间交叉判断
                    swapped = True
                    runtimes=runtimes+1 #记录交换次数
                    dataset[j], dataset[j + 1] = dataset[j + 1], dataset[j] #数据交换
                    stepdata.append(dataset.copy())                            #
                    self.swapAndDraw(tempbar, j, j + 1)                     #绘制动画图
                looptimes=looptimes+1   #记录循环次数
                print('     第{}轮内轮,中间数据={}'.format(j, dataset))  #记录内轮中间数据
            if not swapped:
                break
            print(' 第{}轮外轮,结束数据={}'.format(i,dataset))           #记录外轮中间数据
        print('最终数据=', dataset) #记录最终数据
        plt.ioff()
        return looptimes,runtimes,dataset,stepdata

if __name__ == "__main__":
    import time
    orgdata=init_sortdata(100,8)
    asort=SortClass(orgdata)
    looptimes,runtime,sortdata,stepdata=asort.bubble_sort()
    print('排序前的数据为{}'.format(orgdata))
    print('排序后的数据为{}'.format(sortdata))
    print('循环次数={}'.format(looptimes))
    print('交换次数={}'.format(runtime))
    print('stepdata={}'.format(stepdata))
    #matplotlib动画过程实际上是重构当前帧中图表对象的过程
    def animate(frame):
        for rect, y in zip(bars, stepdata[frame]):  #遍历当前的bars中的rect和数据
            rect.set_height(y)                      #重置每一个bar条的高度
        return bars

    frames=len(stepdata)                            #从步骤数据中获取排序帧数
    xrange=range(len(orgdata))                      #获取bar条的x布局
    fig = plt.figure(2, figsize=(6, 4))             #初始化fig
    plt.title('bubble_sort')
    plt.xticks(range(0, len(orgdata)), rotation=45)  # 进行X轴设置
    bars = plt.bar(xrange, stepdata[0], 0.5)        #初始化bars
    #fig为
    anim = FuncAnimation(fig, animate, frames=frames, interval=200, repeat=False)   #实现动画
    plt.show()
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python与大数据分析 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 代码示例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档