Спектрограмма Python в 3D (как функция спектрограммы в Matlab) - PullRequest
2 голосов
/ 27 июня 2019

У меня следующий вопрос:

У меня есть все значения, которые мне нужны для спектрограммы (scipy.fftpack.fft). Я хотел бы создать 3D-спектрограмму в 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

Желаемый сюжет на питоне, как фигура Матлаба (последний сюжет здесь: https://www.mathworks.com/help/signal/ref/spectrogram.html)

enter image description here

1 Ответ

3 голосов
/ 27 июня 2019

Вам просто нужно привести массивы в правильную форму:

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()
...