我目前正在运行模拟字符串运动的代码,我希望在给定点读取其幅度并将其绘制为时间的函数,从而表示可以从吉他中读取的数据'拾取。由于我是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函数不能被多次调用,而是需要该子图。
答案 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
增加了dt
和dt < 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)