首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用matplotlib动画线条

用matplotlib动画线条
EN

Stack Overflow用户
提问于 2020-08-06 06:29:39
回答 1查看 333关注 0票数 0

我想用matplotlib创建一个动画,用多行,而不是链接。

我可以通过以下方式创建:

代码语言:javascript
复制
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有一个错误

我能做些什么?

谢谢!

我为我糟糕的英语道歉..。

编辑:我的代码在下面

代码语言:javascript
复制
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()

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-07 03:08:48

接下来只有三个步骤:

  • 在初始化阶段创建一些艺术家
  • 更新update函数中的坐标
  • 别忘了还一份最新的艺术家名单。

fargs:元组还是零,可选 传递给func的每个调用的附加参数。

代码语言:javascript
复制
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必须返回修改或创建的所有艺术家的可迭代性。这个信息被闪现算法用来决定图形的哪些部分需要更新。 如果是blit == False,则返回值是未使用的,在这种情况下可以省略。

您的animate_5()最终返回disques。你加入了disques[[]]。空名单不是艺术家。您应该修改逻辑以消除它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63277993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档