从y(x)动画到给定x的y(t)

时间:2014-12-12 11:21:15

标签: python matplotlib args kwargs

我目前正在运行模拟字符串运动的代码,我希望在给定点读取其幅度并将其绘制为时间的函数,从而表示可以从吉他中读取的数据'拾取。由于我是python中的动画新手,因此在演示此动画时获取数据的任务已经证明是一项挑战。这是代码:

import numpy as np
import matplotlib
matplotlib.use("TkAgg")
from matplotlib import pyplot as plt
from math import exp
#import matplotlib.animation as animation

#Power Spectrum
def PowerSpectrum(f):
    return (f*f.conjugate()).real/len(f)**2

#triangular pulse
def triangular_pulse(x, xmean, sigma):
    return np.where(x<xmean,x*sigma/xmean,sigma-(x-xmean)*(sigma/(200-xmean)))

N_masses = 200
T  = 0.0669264714
mu = .03937
cSq = T/mu
c  = np.sqrt(cSq)
dx = 1.0

dt = dx/c
print dt

#Initialize some arrays
x0  = np.arange(N_masses)*dx
y   = np.zeros(N_masses)
vy  = np.zeros(N_masses)
ay  = np.zeros(N_masses)

#setup for animation
fig1 = plt.figure()
plt.ion()
wave, = plt.plot(x0,y)
plt.ylim(-30,30)

#Set Initial conditions (pluck)
# # half-pluck
# y = 30*gaussian_pulse(x0,x0[N_masses/2],2)

# quarter-pluck
y = triangular_pulse(x0,x0[N_masses/10],6)

yprev = y - vy*dt
y1 = []


t=0.0
i=0
while t<1000:
    dydx = (y[1:] - y[:-1])/dx
    ay[1:-1] = ( dydx[1:] - dydx[:-1] )/dx * cSq
    # Notice we update both at the same time
    yprev, y = y, exp(-.00001*t)*(2*y - yprev + ay * dt**2)
    t = t + dt
    y1.append(y[1])
    i += 1

    if i%1==0:
        wave.set_data(x0,y)
        plt.draw()

gauss_hat = np.fft.fft(y1)
freqs = np.fft.fftfreq(len(y1), d=1.0/100)
half_ps = PowerSpectrum(gauss_hat)

#half-pluck y[1] vs. t
plt.plot(range(1000), y1)
plt.xlabel('time')
plt.ylabel('y[1]')
plt.title('y[1] vs. t')

# power spectrum plots
#plt.plot(freqs,half_ps)
#plt.xlabel('frequency (Hz)')
#plt.ylabel('Intensity')

#plt.title('y[1] Power Spectrum (half pluck)')
#plt.title('y[1] Power Spectrum (quarter pluck)')

#plt.grid(True)
#plt.ioff()
plt.show()

动画运行,但没有显示情节。我收到错误:

Traceback (most recent call last):
  File "/Users/defaultuser/Downloads/compare.py", line 69, in <module>
    plt.plot(range(1000), y1)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/pyplot.py", line 2467, in plot
    ret = ax.plot(*args, **kwargs)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/axes.py", line 3893, in plot
    for line in self._get_lines(*args, **kwargs):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/axes.py", line 322, in _grab_next_args
    for seg in self._plot_args(remaining, kwargs):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/axes.py", line 300, in _plot_args
    x, y = self._xy_from_xy(x, y)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/axes.py", line 240, in _xy_from_xy
    raise ValueError("x and y must have same first dimension")
ValueError: x and y must have same first dimension
[Finished in 30.6s with exit code 1]

更新

该错误不再出现,因为代码已被修改为plt.plot(y1),因此授予x和y相同的维度。在评论出负责动画的绘图代码之后,获得了一个很好的图表。因此,我了解到plt.plot函数不能被多次调用,而是需要该子图。

1 个答案:

答案 0 :(得分:1)

追溯中的第一行和最后一行:

  File "/Users/defaultuser/Downloads/compare.py", line 69, in <module>
    plt.plot(range(1000), y1)
...
    raise ValueError("x and y must have same first dimension")

建议range(1000)y1形状不同。 实际上,如果您将代码粘贴到交互式会话中,您将找到

In [17]: len(y1)
Out[17]: 1304

这是有道理的,因为循环将t增加了dtdt < 1

t = 0.0
while t<1000:
    t = t + dt
    y1.append(...)

In [18]: dt
Out[18]: 0.76697947735477701

您可以通过简单地使用plt.plot

的单参数形式来解决问题
plt.plot(y1)

相当于

plt.plot(range(len(y1)), y1)