Python频率与时间图
我正在尝试用Python制作一个.wav文件的频率与时间的图表。目前,我已经有代码可以绘制振幅与时间的图表,以及频率与功率(分贝)的图表。我试过用频率与功率的代码来绘制频率与时间的图表,但没有成功。我知道频率数据是对称的,这意味着我有的频率数据点只有时间数据的一半。如果我保留重复的频率数据,我可以同时绘制这两个图,但我对这样做是否能准确表示频率与时间的关系有些怀疑。
我感觉这个方法可能需要对数据的某些部分使用短时傅里叶变换,然后再绘制结果。说实话,我找到了一些类似的代码,但我对代码的具体操作理解得不太清楚,也很难做出有意义的调整来帮助我实现目标。
总之,我希望有人能提供一些示例代码或方法,帮助我在Python中创建.wav文件的频率与时间图表。非常感谢!如果需要,我可以把我目前使用的代码发上来。
#Import the required functions
from scipy.io.wavfile import read
from scipy.fftpack import fft, fftfreq, fftshift
from scipy.signal import get_window
from math import ceil
from pylab import figure, imshow, clf, gray, xlabel, ylabel
# Read in a wav file
# returns sample rate (samples / sec) and data
rate, data = read('waveTest.wav')
data = data[:,0]
# Define the sample spacing and window size.
dT = 1.0/rate
T_window = 50e-3
N_window = int(T_window * rate)
N_data = len(data)
# 1. Get the window profile
window = get_window('hamming', N_window)
# 2. Set up the FFT
result = []
start = 0
while (start < N_data - N_window):
end = start + N_window
result.append(fftshift(fft(window*data[start:end])))
start = end
result.append(fftshift(fft(window*data[-N_window:])))
result = array(result,result[0].dtype)
# Display results
freqscale = fftshift(fftfreq(N_window,dT))[150:-150]/1e3
figure(1)
clf()
s.imshow(abs(result[:,150:-150]), extent=(5,-5,(N_data*dT-T_window/2.0),T_window/2.0)) #19.04, -19.04, 6.41, 0.025
s.xlabel('Frequency (kHz)')
s.ylabel('Time (sec.)')
s.show()
根据要求,上面是我正在尝试让它工作的代码。实际上,我似乎已经可以正常工作了,但我有几个问题。
1) abs(result[:,150:-150])到底是什么?我知道他是在取傅里叶变换的绝对值(为了去掉复杂部分?)。那么这就是频率吗?
2) 我该如何交换数据,让时间在X轴上,频率在Y轴上?
3) 图像是如何知道哪个频率对应哪个时间的?如果我没理解错,extents的最后两个参数是文件的时间长度和文件应该采取的步长?
4) 是否可以在图表中绘制数据,而不是在图像上?
希望这些问题不会太多,也不会太具体。再次感谢任何能提供的帮助!
1 个回答
1) result[:,150:-150]
这段代码会返回一个 numpy.array
,里面包含了所有的行(每一行对应一个通过fft计算出来的频率)和从 150
到 总列数 - 150
的列。每一列对应一个时间点。没错,abs
是用来计算给定频率的绝对值,这个值大致对应于信号的频率。
2) 在 abs(result[:,150:-150])
中,你需要对这个矩阵进行转置,像这样:abs(result[:,150:-150]).transpose()
。
3) 这个范围参数用于最终图表中的范围设置。因为每一列对应一个特定的时间点,所以这只是一个简单的映射。
4) 你得到的数据表示在特定时间点上,给定频率对信号的贡献(因为在特定时间点上讨论频率是没有意义的,所以是一个时间窗口)。本质上这是一种二维数据。你可以尝试找出在特定时间点上占主导地位的频率,然后把它绘制成一个简单的函数。
另外,你的代码现在是无法运行的。可能是你漏掉了一些变量的定义和从程序其他部分的导入。