Python三维频谱图(类似于Matlab的spectrogram函数)

7

我的问题如下:

我已经有了所有需要制作频谱图所需的值(scipy.fftpack.fft),我想在Python中创建一个三维频谱图。

在MATLAB中,这是非常简单的任务,而在Python中似乎要复杂得多。我尝试过Mayavi、3D绘图的Matplotlib,但都没有成功。

谢谢


我的代码:

import numpy as np
import pandas as pd
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.collections import PolyCollection

fs = 11240.
t = 10
time = np.arange(fs*t) / fs
frequency = 1000.
mysignal = np.sin(2.0 * np.pi * frequency * time)

nperseg = 2**14
noverlap = 2**13
f, t, Sxx = signal.spectrogram(mysignal, fs, nperseg=nperseg,noverlap=noverlap)

myfilter = (f>800) & (f<1200)

fig,ax = plt.subplots()

plt.pcolormesh(t, f[myfilter], 10*np.log10(Sxx[myfilter, :]), cmap='jet')
plt.show()

fig = plt.figure()
ax = fig.gca(projection='3d')
x = []
y = []

for counter,i in enumerate(f):
    x.append(np.array([i for k in t]))
    y.append(t)

ax.plot_surface(np.array(x), np.array(y), 10.0*np.log10(Sxx), cmap=cm.coolwarm)
plt.show()


类似未解决的问题:如何在Python中将频谱图转换为三维图。

希望在Python中得到类似于Matlab图形的图表(最后一个图表在此处:https://www.mathworks.com/help/signal/ref/spectrogram.html

enter image description here


3
请提供一个最小可复现示例,展示您目前所做的工作。 - DrBwts
你有相应的MATLAB代码吗? - Dan
OP提出了一个很好的问题。Matlab函数只是一个内置函数(https://www.mathworks.com/help/signal/ref/spectrogram.html)。我想像OP一样在Python中实现相同的功能。 - seralouk
1
还有这个:https://dev59.com/6ajka4cB1Zd3GeqPDsF4 但是不是很清楚。 - user8925657
你想让 xy 看起来像什么?特别是,你想用 [i for k in t] 做什么?你看过 np.meshgrid 来生成 xy 吗? - Dan
你试过使用specgram了吗? - Dan
2个回答

7

您只需要将数组排列正确:

fs = 11240.
t = 10
time = np.arange(fs*t) / fs
frequency = 1000.
mysignal = np.sin(2.0 * np.pi * frequency * time)

nperseg = 2**14
noverlap = 2**13
f, t, Sxx = signal.spectrogram(mysignal, fs, nperseg=nperseg,noverlap=noverlap)

myfilter = (f>800) & (f<1200)

f = f[myfilter]
Sxx = Sxx[myfilter, ...]

fig = plt.figure()
ax = fig.gca(projection='3d')

ax.plot_surface(f[:, None], t[None, :], 10.0*np.log10(Sxx), cmap=cm.coolwarm)
plt.show()

如果t是一个时间戳列表,我会收到一个错误:TypeError: list indices must be integers, not tuple。例如列表:t = [Timestamp('2016-09-14 01:43:13'), Timestamp('2016-09-14 01:43:14')...] - user8925657

4
这是@Nils Werner答案的改编版本,变量名称有所不同,并且包含了完整的导入集合。
import numpy as np
import matplotlib.pyplot as plt 
from scipy import signal # spectrogram function
from matplotlib import cm # colour map

# basic config
sample_rate = 11240.  # 
sig_len_secs = 10
frequency = 2000.

# generate the signal
timestamps_secs = np.arange(sample_rate*sig_len_secs) / sample_rate
mysignal = np.sin(2.0 * np.pi * frequency * timestamps_secs) 

# extract the spectrum
freq_bins, timestamps, spec = signal.spectrogram(mysignal, sample_rate)

# 3d plot
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.plot_surface(freq_bins[:, None], timestamps[None, :], 10.0*np.log10(spec), cmap=cm.coolwarm)
plt.show()

3D plot of a spectrum


缺少 from mpl_toolkits.mplot3d import Axes3D,并将最后一个samplerate重命名为sample_rate - Jean Claveau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接