Как определить параметр fun c для matplotlib FuncAnimation - PullRequest
1 голос
/ 07 марта 2020

После многих попыток я в недоумении от того, как забавный параметр c работает для анимации гистограмм. У меня есть следующий код:

# 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 () я хочу анимировать изменение порядка на гистограмме. Я определил кадры как мой генератор, но я не понимаю, что мне нужно передать параметру "fun c". Я искал примеры в Интернете, но до сих пор не понимаю, что мне нужно здесь разместить. Всякий раз, когда я запускаю код, я получаю ошибки, которые не объясняют проблему.

1 Ответ

1 голос
/ 07 марта 2020

Внутри animate() вам нужно получить следующее состояние частично отсортированного списка, и вам необходимо соответствующим образом обновить гистограмму.

Вы получаете обновленный список, перебирая sorter, но в зависимости от того, какой слой вложенного for loops вы помещаете оператор yield, ваши обновления происходят более или менее часто. В настоящее время вы можете выдать отсортированный список только один раз. Я переместил его на 1 oop вниз, но вы можете делать более частые обновления:

Обновление графика выполняется через h_bar (См. Также этот вопрос для обновления гистограмм. в общем)

Я упустил некоторые части кода, чтобы сосредоточиться на основных вещах.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...