【问题标题】:Slow and smooth drawing lines python matplotlib缓慢而流畅的绘制线条 python matplotlib
【发布时间】:2015-02-07 17:44:25
【问题描述】:

我正在使用 matplotlib 绘制平滑线等图形。对我来说画画没问题,但我在动画方面有问题。

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

所以,我有数组,比如:

a = [0,1,2,4,5,8,9,12,14,18,22,17,30,37,29,45]

我需要点对点平滑地绘制它。 现在我有了这个字符串:

for i in range(len(a)-1):
    desty = np.append(desty,np.linspace(a[i],a[i+1],n))
    destx = np.append(destx,np.linspace(i,i+1,n))

这让我可以毫无问题地画线(和动画:))

完整代码:

# First set up the figure, the axis, and the plot element we want to animate
fig = plt.figure()
ax = plt.axes(xlim=(0, 50), ylim=(0, 50))
line, = ax.plot([], [], lw=2)
global x
global y
global n
global a
n=5
a = [0,1,2,4,5,8,9,12,14,18,22,17,30,37,29,45]

global desty,destx
desty = np.linspace(0,0,n)
destx = np.linspace(0,0,n)
for i in range(len(a)-1):
    desty = np.append(desty,np.linspace(a[i],a[i+1],n))
    destx = np.append(destx,np.linspace(i,i+1,n))
# initialization function: plot the background of each frame
def init():
    line.set_data([], [])
    return line,
# animation function.  This is called sequentially
def animate(i):
    global destx
    global desty
    x=destx
    y=desty
    line.set_data(x, y)
    return line,

# call the animator.  blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=200, interval=20, blit=True)
plt.show()

只允许我绘制它,但我如何才能缓慢而平滑地点对点地绘制它?

我使用的是 python 2.7、centos 7。

【问题讨论】:

    标签: python numpy matplotlib lines


    【解决方案1】:

    您可以将您的绘图程序精简到:

    import numpy as np
    import random as random
    from matplotlib import pyplot as plt
    from matplotlib import animation
    # First set up the figure, the axis, and the plot element we want to animate
    fig = plt.figure()
    ax = plt.axes(xlim=(0, 50), ylim=(0, 50))
    line, = ax.plot([], [], lw=2)
    
    n=5
    a = [0,1,2,4,5,8,9,12,14,18,22,17,30,37,29,45]
    
    x = []
    y = []
    
    # initialization function: plot the background of each frame
    def init():
        line.set_data([], [])
        return line,
    
    # animation function.  This is called sequentially
    def animate(i):
        x.append(np.linspace(i,i+1,n))
        y.append(np.linspace(a[i],a[i+1],n))
        line.set_data(x,y)
    
        return line,
    
    # call the animator.  blit=True means only re-draw the parts that have changed.
    anim = animation.FuncAnimation(fig, animate, np.arange(0,len(a)-1) ,init_func=init, 
                                   interval=200, blit=True, repeat=False)
    
    plt.show()
    

    注意事项:

    • 你不需要global 变量来工作
    • 您不想在动画之外设置 xy 以便情节发展(在您的情况下,您已经设置了完整的 xy 以便动画只会绘制整个图表)
    • 您需要将一个interable 传递给animatei);这是FuncAnimation - np.arange(0,len(a)-1) 的第三个输入。
    • repeat=False 设置为在一次运行后停止并避免“关闭”曲线
    • 我增加了interval,让剧情发展更慢

    【讨论】:

    • 感谢您提及matplotlib.animation API。
    【解决方案2】:

    您需要在您的动画函数中使用i,否则它只会一遍又一遍地绘制相同的东西,这就是您所看到的。

    import numpy as np
    import random as random
    from matplotlib import pyplot as plt
    from matplotlib import animation
    
    # First set up the figure, the axis, and the plot element we want to animate
    fig = plt.figure()
    ax = plt.axes(xlim=(0, 50), ylim=(0, 50))
    line, = ax.plot([], [], lw=2)
    global x
    global y
    global n
    global a
    n=5
    a = [0,1,2,4,5,8,9,12,14,18,22,17,30,37,29,45]
    
    global desty,destx
    desty = np.linspace(0,0,n)
    destx = np.linspace(0,0,n)
    plot_me_x = []
    plot_me_y = []
    for i in range(len(a)-1):
        desty = np.append(desty, np.linspace(a[i],a[i+1],n))
        destx = np.append(destx, np.linspace(i,i+1,n))
        plot_me_x.append(np.array(destx))   # keep a copy of the intermediaries to plot later
        plot_me_y.append(np.array(desty))
    # initialization function: plot the background of each frame
    def init():
        line.set_data([], [])
        return line,
    # animation function.  This is called sequentially
    def animate(i):
        global destx
        global desty
        x=plot_me_x[i]
        y=plot_me_y[i]
        line.set_data(x, y)
        return line,
    
    # call the animator.  blit=True means only re-draw the parts that have changed.
    anim = animation.FuncAnimation(fig, animate, init_func=init,
                                   frames=len(a)-1, interval=20, blit=True)
    plt.show()
    

    为了使每个动画的情节看起来不同,i 必须索引在每次迭代中看起来不同的东西。虽然destydestx是在构建它们的迭代中逐渐附加的,但最终的结果不是这个逐渐构建而是一个单一的东西,所以你需要节省这个构建的中介。我用plot_me_xy 做到了这一点。

    我写了这个答案,对 OP 的代码进行了最小的更改,以明确错误在哪里。总体而言,@Schorsch 所做的更改导致了整体上更清洁的方法(例如,没有全局变量)。

    【讨论】:

    • 谢谢你,非常有帮助的回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多