【问题标题】:How to define the func parameter for matplotlib FuncAnimation如何为 matplotlib FuncAnimation 定义 func 参数
【发布时间】:2020-03-08 03:42:48
【问题描述】:

经过多次尝试,我对 func 参数如何为条形图设置动画感到茫然。我有以下代码:

# Imports
import random
from tkinter import *
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import pandas as pd

# Functions
def gen_rand_array(no=500):
    return_list = []
    for x in range(no):
        return_list.append(random.randint(1,101))
    return return_list

def bubblesort(list):
    for i in range(len(list)):
        for j in range(0,len(list) - i - 1):
            if list[j] > list[j+1]:
                list[j],list[j+1] = list[j+1],list[j]
    yield list

# Runtime
def main():
    # User parameters
    win = Tk()
    win.title("Set Parameters")
    win.minsize(500,500)
    array_size = Scale(win,from_=2,to=5000,orient="horizontal",label="Use the slider to set the size of the initial array:",length=450,sliderlength=10).pack()
    win.mainloop()
    # Build random unsorted list
    unsorted_vals = []
    for index,value in enumerate(gen_rand_array()):
        unsorted_vals.append(value)

    # Formatting
    fig,ax = plt.subplots(figsize=(15,8))

    def animate(x):
        ax.set_title("Test")
        ax.set_ylim(0,100)
        for key,spine in ax.spines.items():
            spine.set_visible(False)
        ax.tick_params(bottom="off",left="off",right="off",top="off")
        ax.set_yticks([])
        ax.set_xticks([])

    ax.bar(range(len(unsorted_vals)), unsorted_vals)

    # Visualise the sort
    sorter = bubblesort(unsorted_vals)

    anim = animation.FuncAnimation(fig,frames=sorter,func=animate)

    plt.show()

main()

因此,对于bubblesort() 的每次迭代,我都希望在条形图上按顺序对更改进行动画处理。我已经将框架定义为我的生成器,但我不明白我需要传递给“func”参数的内容。我一直在网上查找示例,但我仍然不明白我需要在这里放什么。每当我运行代码时,我都会遇到无法解释问题的错误。

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    animate() 中,您需要获取部分排序列表的下一个状态,并且需要相应地更新条形图。

    您通过遍历sorter 获得更新的列表,但是 根据您放置yield 语句的嵌套for loops 的哪一层,您的更新或多或少频繁。目前,您只产生一次排序列表。我将它向下移动了一个循环,但您可以进行更频繁的更新:

    图的更新是通过h_bar 执行的(有关更新条形图的一般信息,另请参见this question

    我留下了部分代码,专注于主要内容。

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
    
    def bubblesort(list):
        for i in range(len(list)):
            for j in range(0, len(list) - i - 1):
                if list[j] > list[j+1]:
                    list[j], list[j+1] = list[j+1], list[j]
                     # yield list  # two elements swapped place
            yield list  # ith bubble loop completed 
        # yield list  # sorted list
    
    n = 100
    unsorted_vals = np.random.randint(0, 101, size=n)
    sorter = bubblesort(unsorted_vals)
    
    fig, ax = plt.subplots(figsize=(15, 8))
    ax.set_ylim(0, 100)
    for key, spine in ax.spines.items():
        spine.set_visible(False)
    ax.set_yticks([])
    ax.set_xticks([])
    
    h_bar = ax.bar(range(len(unsorted_vals)), unsorted_vals)
    
    def animate(x):
        current_list = sorter.__next__()
        for rect, h in zip(h_bar, current_list):
            rect.set_height(h)
    
    anim = animation.FuncAnimation(fig, frames=n, func=animate, repeat=False)
    plt.show()
    

    现在你总是更新整个条形图,当只需要更新交换位置的两个元素时,也许你可以通过以下方式加速动画:

    def bubblesort(list):
        for i in range(len(list)):
            for j in range(0, len(list) - i - 1):
                if list[j] > list[j+1]:
                    list[j], list[j+1] = list[j+1], list[j]
                    yield list, j
    
    def animate(x):
        current_list, idx = sorter.__next__()
        h_bar[idx].set_height(current_list[idx])
        h_bar[idx+1].set_height(current_list[idx+1])
        return h_bar
    

    【讨论】:

    • 非常感谢您的精彩解释。我正要出门,但根据你上面写的内容,我回来后会修改我的代码,然后再试一次。
    猜你喜欢
    • 1970-01-01
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-14
    • 2013-11-19
    • 2021-02-06
    相关资源
    最近更新 更多