Анимируйте линии с помощью matplotlib - PullRequest
0 голосов
/ 06 августа 2020

Я хочу создать анимацию с помощью matplotlib, с несколькими строками, не связанными.

Я могу создать это с помощью:

def animate(i) :
    a = []
    a.append((x1,x2))
    a.append((y1,y2))
    a.append('b')
    a.append((x3,x4))
    a.append((y3,y4))
    a.append('r')
    a.append((x5,x6))
    a.append((y5,y6))
    a.append('g')
    a = plt.plot(*a)
    return a
ani = animation.FuncAnimation(fig, animate, frames = 10, blit = True, interval = 50, save_count = 50, repeat = False) 

С помощью этого кода я не могу установить строку linewidth.

Я пытался добавить plt.plot прямо в a, но у меня ошибка zorder

Что делать?

Спасибо!

PS: Прошу прощения за мой бедный Энгли sh ...

Редактировать: мой код ниже

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.animation as animation # pour l'animation
import matplotlib.lines as lines

nombre_etapes = 0

nombre_disques = 4

etapes = []
#on crée l'état initial : tous les disques sur le bâton 0
etapes.append([[i for i in range(nombre_disques, 0, -1)], [], []])
print("état initial : ")
print(etapes)

mouvements = [None]
def hanoi(n, origine, destination, intermediaire) :
    global nombre_etapes
    #global etapes
    if n > 0 :        
        hanoi(n - 1, origine, intermediaire, destination)
        nombre_etapes += 1
        #on crée le nouvel état        
        etat_actuel = [x for x in etapes[-1]]
        #print("état actuel avant mouvement", etat_actuel)
        disque_a_bouger = etat_actuel[origine].pop()
        #print("disque qui bouge : {}".format(disque_a_bouger))
        etat_actuel[destination].append(disque_a_bouger)
        #print("état actuel après mouvement", etat_actuel)
        etapes.append(etat_actuel)
        #print("etapes : ")
        #print(etapes)
        print(str(origine) + " --> " + str(destination))
        mouvements.append([origine, destination])
        hanoi(n - 1, intermediaire, destination, origine)
        nombre_etapes += 1

#longueurs pour dessin
rayon = 10
ecart_vertical = 0.5
epaisseur_disque = 0.5
epaisseur_baton = 2

hanoi(nombre_disques,0,2,1)
#print(mouvements)

etat = [[i for i in range(nombre_disques, 0, -1)], [], []]

def dessine_batons() :
    batons = []
    for idBaton in range(3) :
        abscisse = (2 * idBaton + 1) * nombre_disques * rayon + 2 * idBaton * rayon
        ordonnee_1 = 0
        ordonnee_2 = 4 * ecart_vertical + epaisseur_disque * nombre_disques
        batons.append((abscisse, abscisse))
        batons.append((ordonnee_1, ordonnee_2))
        batons.append('b')
    #print(batons)
    batons = plt.plot(*batons)
    return batons



fig, ax = plt.subplots()
abscisse = 3 * nombre_disques * rayon + 2 * rayon
ordonnee = ecart_vertical
disques = [[]]

couleurs = ["", "red", "blue", "grey", "green", "black", "cyan", "magenta", "crimson", "pink", "orange"]
for idDisque in range(nombre_disques, 0, -1) :
    abscisses = [abscisse - idDisque * rayon, abscisse + idDisque * rayon]
    ordonnees = [ordonnee, ordonnee]
    ordonnee += ecart_vertical + epaisseur_disque
    disque, = ax.plot(abscisses, ordonnees, c = couleurs[idDisque], linewidth = 20, zorder = 1)
    disques.append(disque)




def animate_5(idEtape, disques) :
    if idEtape != 0 :         
        #on récupère le mouvement
        mouvement = mouvements[idEtape]
        origine, destination = mouvement
        disque_qui_bouge = etat[origine].pop()
        etat[destination].append(disque_qui_bouge)
    for idBaton in range(3) :
        abscisse = (2 * idBaton + 1) * nombre_disques * rayon + 2 * idBaton * rayon
        ordonnee = ecart_vertical
        for disque in etat[idBaton] :
            abscisses = [abscisse - disque * rayon, abscisse + disque * rayon]
            ordonnees = [ordonnee, ordonnee]
            disques[disque].set_data(abscisses, ordonnees)
            disques[disque].set_zorder(disque)
            ordonnee += ecart_vertical + epaisseur_disque
    plt.pause(0.1)
    return disques



plt.axis([-10, 5 * nombre_disques * rayon + 4 * rayon + nombre_disques * rayon + 5, 0, 4 * ecart_vertical + epaisseur_disque * nombre_disques + 5])

ani = animation.FuncAnimation(fig, animate_5, init_func = dessine_batons, fargs = [disques], frames = len(mouvements), blit = False, interval = 50, save_count = 50, repeat = False) 


plt.show()

'

1 Ответ

1 голос
/ 07 августа 2020

Всего три шага:

  • Создайте несколько художников на этапе инициализации
  • Обновите их координаты в функции update
  • Не забудьте для возврата списка обновленных исполнителей.

fargs : кортеж или None, необязательно

Дополнительные аргументы, передаваемые при каждом вызове fun c.

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

plt.rcParams['lines.linewidth'] = 5

x = np.linspace(0, 7.5, 100)
y1 = np.sin(x)
y2 = np.sin(x+0.5)
y3 = [0] * len(x)
ys = [y1, y2, y3]

fig, ax = plt.subplots()

line1, = ax.plot(x, y1, label='zorder=2', zorder=2, color='orange') #bottom
line2, = ax.plot(x, y2, label='zorder=4', zorder=4, color='blue')
line3, = ax.plot(x, y3, label='zorder=3', zorder=3, color='lightgrey', linewidth=8)
lines = [line1, line2, line3]

def update(num, x, ys, lines):
    for i in range(len(ys)):
        lines[i].set_data(x[:num], ys[i][:num])

    if num > len(x)/2:
        line1.set_linewidth(10)
        line1.set_zorder(5)       #upper
        line2.set_zorder(1)       #bottom

    print(line1.get_zorder())

    return lines


ani = animation.FuncAnimation(fig, func=update, frames=len(x), fargs=[x, ys, lines],
                            blit = True, interval = 50, save_count = 50, repeat = False)

plt.show()

Ссылка:

Согласно matplotlib.animation.FuncAnimation

If blit == True, fun c должен возвращать итерабельность всех художников , которые были изменены или созданы. Эта информация используется алгоритмом блиттинга для определения, какие части рисунка необходимо обновить.

Возвращаемое значение не используется, если blit == False, и может быть опущено в этом случае.

Ваш animate_5() наконец-то вернет disques. Вы инициализируете disques с [[]]. Пустой список не исполнителей . Вы должны изменить логику, чтобы избавиться от нее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...