【问题标题】:Animate lines with matplotlib使用 matplotlib 动画线条
【发布时间】:2020-08-06 06:29:39
【问题描述】:

我想用 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) 

使用此代码,我无法设置线条的线宽。

我尝试将 plt.plot 直接添加到 a,但是 zorder 出现错误

我能做什么?

谢谢!

PS : 我为我糟糕的英语道歉...

编辑:我的代码在下面

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()

'

【问题讨论】:

    标签: python matplotlib animation


    【解决方案1】:

    只需三个步骤:

    • 在初始化阶段创建一些艺术家
    • 在update 函数中更新它们的坐标
    • 不要忘记返回更新的艺术家列表。

    fargs:元组或无,可选

    附加参数传递给每次调用func。

    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

    如果blit == True,func 必须返回一个可迭代的所有artists 被修改或创建的。此信息由 blitting 使用 算法来确定图形的哪些部分必须更新。

    如果blit == False,返回值是未使用的,可以省略 那个案例。

    您的animate_5() 最终返回disques。你用[[]]初始化disques。空列表不是艺术家。您应该修改逻辑以摆脱它。

    【讨论】:

    • 感谢您的回答。不幸的是,我没有很好地解释我想要什么。我有几个段,必须在每一帧计算四肢。例如,红色部分向右,蓝色部分向下。我试图调整您的代码,但出现错误:AttributeError: 'list' object has no attribute 'get_zorder'
    • @rognntudjuu 因为我不知道你怎么称呼get_zorder,所以我只是举个例子如何调用它并设置线宽。
    • 我已经编辑了我的帖子以添加我的代码。它适用于 blit = False,但我有一个 blit = True 错误:'AttributeError:'list' object has no attribute 'get_zorder''
    • @rognntudjuu 你能正确地初始化你的变量,这样我就可以告诉你哪里出错了。
    • 在我检查它是否支持动画之前,我已经添加了我想将此代码放在我的 Numworks 上的所有代码......但我想知道该怎么做
    猜你喜欢
    • 2016-07-27
    • 1970-01-01
    • 2019-04-17
    • 1970-01-01
    • 1970-01-01
    • 2019-12-11
    • 2022-11-07
    • 2018-07-12
    • 2021-02-25
    相关资源
    最近更新 更多