不断改变移动matplotlib动画的方向?

时间:2017-12-14 00:47:18

标签: python animation matplotlib

我一直在使用来自animation的{​​{1}}模块,我意识到我无法在两个极限之间(在这种情况下介于-180°和180°之间)有效地进行正弦波循环。

喜欢这样......

matplotlib

原因是因为我正在使用import numpy as np from matplotlib import pyplot as plt from matplotlib import animation fig = plt.figure() ax = plt.axes(xlim=(0, 0.04), ylim=(-1.5, 1.5)) # initialize moving plots line1, = ax.plot([], [], linewidth=2, label='sine') line2, = ax.plot([], [], label='cosine') ax.legend() ax.grid() def animate(i): step = np.pi/30 # loop by hand... if i < 30: phase = i*step elif 30 <= i < 90: phase = -i*step elif 90 <= i < 150: phase = i*step elif 150 <= i < 210: phase = -i*step else: phase = i*step x = np.linspace(0, 0.04, 1000) y1 = np.sin( 2*np.pi*50*x - phase ) y2 = 0.5*np.cos( 2*np.pi*50*x + phase ) line1.set_data(x, y1) line2.set_data(x, y2) print('i:',i) # debug i return line1, line2 anim = animation.FuncAnimation(fig, animate, interval=250, blit=True) plt.show() 变量,该变量用于帧计数并且仅随时间增加。有没有办法无限期地循环,如果条件直到时间结束?

this answer我发现从绘图中刷新数据是可行的,我设法让它几乎像我想要的那样循环。

改编示例...(解决方法未完成)

i

问题在于它不允许我关闭窗口,就像使用import matplotlib.pyplot as plt import numpy as np def Yvalue(t, phase): """Function to plot""" w = 2*np.pi*50 return np.sin(w*t + phase) plt.ion() # You probably won't need this if you're embedding things in a tkinter plot... step = np.pi/30 # steps for phase shifting t = np.linspace(0, 0.04) # x values y1 = Yvalue(t, 0) # y values # starts figure fig = plt.figure() ax = plt.axes(xlim=(0, 0.04), ylim=(-1.5, 1.5)) # Returns a tuple of line objects, thus the comma line1, = ax.plot(t, y1, linewidth=2, label='sine') # static plot (cosine) ax.plot(t, np.cos(2*np.pi*50*t), label='cosine static') ax.legend() ax.grid() # initial values phase = 0 direction = 1 # 1: shifting plot to left; 0: shifting plot to right UpperLimit = np.pi LowerLimit = -np.pi # magic begins... for something in range(210): # while 1: if direction and phase < UpperLimit: phase += step direction = 1 else: phase -= step direction = 0 # condition that helps to return to left shifting if phase < LowerLimit: direction = 1 line1.set_ydata( Yvalue(t, phase) ) fig.canvas.draw() 模块一样。因此,当 while循环 更改 for循环时,必须手动终止该程序。

2 个答案:

答案 0 :(得分:0)

我不知道我是否理解您的问题,因为我在for

中使用第二种方法(在animate循环中使用)时没有看到问题
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation

fig = plt.figure()
ax = plt.axes(xlim=(0, 0.04), ylim=(-1.5, 1.5))

# initialize moving plots
line1, = ax.plot([], [], linewidth=2, label='sine')
line2, = ax.plot([], [], label='cosine')

ax.legend()
ax.grid()

# -------------------------------------------------

def func1(t, phase):
    """Function to plot"""
    w = 2*np.pi*50
    return np.sin( w*t + phase)

def func2(t, phase):
    """Function to plot"""
    w = 2*np.pi*50
    return np.sin( w*t - phase)

# -------------------------------------------------

t = np.linspace(0, 0.04)
step = np.pi/30

UpperLimit = np.pi
LowerLimit = -np.pi

direction = 1
phase = 0

def animate(i):
    global direction 
    global phase

    if direction:
        phase += step
        if phase >= UpperLimit:
            direction = 0
    else:
        phase -= step
        if phase < LowerLimit:
            direction = 1

    line1.set_data(t, func1(t, phase))
    line2.set_data(t, func2(t, phase))

    return line1, line2

anim = animation.FuncAnimation(fig, animate, interval=250, blit=True)

plt.show()

甚至没有变量direction

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

fig = plt.figure()
ax = plt.axes(xlim=(0, 0.04), ylim=(-1.5, 1.5))

# initialize moving plots
line1, = ax.plot([], [], linewidth=2, label='sine')
line2, = ax.plot([], [], label='cosine')

ax.legend()
ax.grid()

# -------------------------------------------------

def func1(t, phase):
    """Function to plot"""
    w = 2*np.pi*50
    return np.sin( w*t + phase)

def func2(t, phase):
    """Function to plot"""
    w = 2*np.pi*50
    return np.sin( w*t - phase)

# -------------------------------------------------

t = np.linspace(0, 0.04)
step = np.pi/30

UpperLimit = np.pi
LowerLimit = -np.pi

phase = 0

def animate(i):
    global phase
    global step

    phase += step

    if phase >= UpperLimit or phase <= LowerLimit:
       step = -step

    line1.set_data(t, func1(t, phase))
    line2.set_data(t, func2(t, phase))

    return line1, line2

anim = animation.FuncAnimation(fig, animate, interval=250, blit=True)

plt.show()

答案 1 :(得分:0)

您通常不会使用动画功能本身来计算其动画参数。相反,您可以使用frames参数将该参数作为参数提供。

在这种情况下,您希望动画函数将phase作为参数。要创建phase,这是一种锯齿函数,你可以使用像

这样的numpy
a = np.linspace(0,1, 30, endpoint=False)
phase = np.concatenate((a, 1-a, -a, a-1))*np.pi

完整示例:

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

fig = plt.figure()
ax = plt.axes(xlim=(0, 0.04), ylim=(-1.5, 1.5))
line1, = ax.plot([], [], linewidth=2, label='sine')
line2, = ax.plot([], [], label='cosine')
ax.legend()
ax.grid()

x = np.linspace(0, 0.04, 1000)

a = np.linspace(0,1, 30, endpoint=False)
phase = np.concatenate((a, 1-a, -a, a-1))*np.pi

def animate(phase):
    y1 = np.sin( 2*np.pi*50*x - phase )
    y2 = 0.5*np.cos( 2*np.pi*50*x + phase )
    line1.set_data(x, y1)
    line2.set_data(x, y2)
    return line1, line2

anim = animation.FuncAnimation(fig, animate, frames=phase, interval=50, blit=True)

plt.show()

enter image description here

相关问题