FuncAnimation вызывается слишком много раз

Nov 08 2020

Это продолжение предыдущего вопроса, который я задал . Я заметил, что значения, используемые для обновления моей круговой диаграммы, неверны. У меня есть список z, который обновляется numитератором в моей функции FuncAnimation с именем update. Вот код, с которым я работаю:

import numpy as np
import matplotlib.animation as animation
from matplotlib import pyplot as plt 

numbers = [[6.166, 5.976, 3.504, 7.104, 5.14],
 [7.472, 5.888, 3.264, 6.4825, 7.168],
 [7.5716, 9.936, 3.6, 8.536, 2.808],
 [2.604, 2.296, 0.0, 6.144, 4.836],
 [7.192, 4.932, 0.0, 6.016, 8.808],
 [7.192, 5.5755, 3.694, 9.376, 9.108],
 [7.63616, 5.912, 3.968, 6.672, 3.192],
 [3.41049, 5.44, 4.004, 7.212, 3.6954],
 [4.3143, 6.364, 3.584, 7.44, 5.78],
 [4.992, 3.9692, 4.272, 0.0, 2.528]]
numbers = np.array(numbers)

colors = ["yellow", "red", "purple", "blue", "green"]
explode = [0.01, 0.01, 0.01, 0.01, 0.01]
labels = ["DM", "Bard", "Warlock", "Paladin", "Ranger"]
z = np.array([0,0,0,0,0]).astype(np.float)

fig,ax = plt.subplots()
y = []
def update(num):
    global y
    global z
    ax.clear()
    ax.axis('equal')     
    z += numbers[num]
    y.append(z)
    
    #output of different vairables#
    print(num, z, sum(z), len(y))

    pie = ax.pie(z, explode=explode, labels=labels, colors=colors, 
                 autopct='%1.1f%%', shadow=True, startangle=140)
    ax.set_title(sum(z))    
    
ani = animation.FuncAnimation(fig, update, frames=range(10), repeat=False)
ani.save('test.gif', writer='pillow', fps=1)

Результат print()функции выглядит так:

0 [6.166 5.976 3.504 7.104 5.14 ] 27.89 1
0 [12.332 11.952  7.008 14.208 10.28 ] 55.78 2
1 [19.804  17.84   10.272  20.6905 17.448 ] 86.05450000000002 3
2 [27.3756 27.776  13.872  29.2265 20.256 ] 118.5061 4
3 [29.9796 30.072  13.872  35.3705 25.092 ] 134.3861 5
4 [37.1716 35.004  13.872  41.3865 33.9   ] 161.3341 6
5 [44.3636 40.5795 17.566  50.7625 43.008 ] 196.27959999999996 7
6 [51.99976 46.4915  21.534   57.4345  46.2    ] 223.65975999999995 8
7 [55.41025 51.9315  25.538   64.6465  49.8954 ] 247.42165 9
8 [59.72455 58.2955  29.122   72.0865  55.6754 ] 274.90395 10
9 [64.71655 62.2647  33.394   72.0865  58.2034 ] 290.66515 11
0 [70.88255 68.2407  36.898   79.1905  63.3434 ] 318.55514999999997 12

Вывод на печать показывает, numbers[0]что добавляется к самому себе до того, как numитератор увеличится на 1. После этого он работает, как задумано, где numbers[1]сквозные numbers[9]элементы складываются вместе. Но опять же, почему-то numbers[0]добавляется numbers[9].

В первом кадре результирующего gif отображаются эти данные: [12.332 11.952 7.008 14.208 10.28 ] 55.78а в последнем кадре отображаются эти данные: и [64.71655 62.2647 33.394 72.0865 58.2034 ] 290.66515это нормально, поскольку именно здесь цикл должен остановиться.

Я хотел бы знать, что я делаю не так в данном случае; как я могу исправить неожиданное поведение num?

Ответы

2 DizietAsahi Nov 08 2020 at 22:51

Без init_func=передачи FuncAnimationон будет использовать саму функцию анимации в качестве начального состояния, которое вызывает ваш дублет 0. В документации указано :

init_func: вызываемый, необязательный

Функция, используемая для рисования четкой рамки. Если не указан, будут использоваться результаты рисования из первого элемента в последовательности кадров. Эта функция будет вызвана один раз перед первым кадром.

Вы можете просто передать пустую функцию, чтобы устранить проблему.

def init():
    pass

(...)

ani = animation.FuncAnimation(fig, update, frames=range(10), init_func=init, repeat=False)