My question is the following:
I have all the values that I need for a spectrogram (scipy.fftpack.fft
). I would like to create a 3D spectrogram in python.
In MATLAB this is a very simple task, while in python it seems much more complicated. I tried mayavi, 3D plotting matplotlib but I have not managed to do this.
Thanks
My code:
JavaScript
x
39
39
1
import numpy as np
2
import pandas as pd
3
import numpy as np
4
from scipy import signal
5
import matplotlib.pyplot as plt
6
from mpl_toolkits.mplot3d import Axes3D
7
from matplotlib import cm
8
from matplotlib.collections import PolyCollection
9
10
fs = 11240.
11
t = 10
12
time = np.arange(fs*t) / fs
13
frequency = 1000.
14
mysignal = np.sin(2.0 * np.pi * frequency * time)
15
16
nperseg = 2**14
17
noverlap = 2**13
18
f, t, Sxx = signal.spectrogram(mysignal, fs, nperseg=nperseg,noverlap=noverlap)
19
20
myfilter = (f>800) & (f<1200)
21
22
fig,ax = plt.subplots()
23
24
plt.pcolormesh(t, f[myfilter], 10*np.log10(Sxx[myfilter, :]), cmap='jet')
25
plt.show()
26
27
fig = plt.figure()
28
ax = fig.gca(projection='3d')
29
x = []
30
y = []
31
32
for counter,i in enumerate(f):
33
x.append(np.array([i for k in t]))
34
y.append(t)
35
36
ax.plot_surface(np.array(x), np.array(y), 10.0*np.log10(Sxx), cmap=cm.coolwarm)
37
plt.show()
38
39
Similar unanswered question: How to convert a spectrogram to 3d plot. Python
Desired plot in python like Matlab’s figure (last plot here: https://www.mathworks.com/help/signal/ref/spectrogram.html)
Advertisement
Answer
You just need to get your arrays in the right shape:
JavaScript
1
21
21
1
fs = 11240.
2
t = 10
3
time = np.arange(fs*t) / fs
4
frequency = 1000.
5
mysignal = np.sin(2.0 * np.pi * frequency * time)
6
7
nperseg = 2**14
8
noverlap = 2**13
9
f, t, Sxx = signal.spectrogram(mysignal, fs, nperseg=nperseg,noverlap=noverlap)
10
11
myfilter = (f>800) & (f<1200)
12
13
f = f[myfilter]
14
Sxx = Sxx[myfilter, ]
15
16
fig = plt.figure()
17
ax = fig.gca(projection='3d')
18
19
ax.plot_surface(f[:, None], t[None, :], 10.0*np.log10(Sxx), cmap=cm.coolwarm)
20
plt.show()
21