Introduction
Ce tutoriel vous guidera tout au long du processus de tracé de la densité spectrale de puissance (DSP) à l'aide de la bibliothèque Matplotlib en Python. La DSP est un tracé couramment utilisé dans le domaine du traitement du signal. NumPy dispose de nombreuses bibliothèques utiles pour calculer une DSP, et nous allons montrer quelques exemples de la manière dont cela peut être accompli et visualisé avec Matplotlib.
Conseils sur la machine virtuelle
Une fois le démarrage de la machine virtuelle terminé, cliquez dans le coin supérieur gauche pour basculer vers l'onglet Carnet de notes pour accéder au carnet Jupyter pour pratiquer.
Parfois, vous devrez peut-être attendre quelques secondes pour que le carnet Jupyter ait fini de charger. La validation des opérations ne peut pas être automatisée en raison des limitations du carnet Jupyter.
Si vous rencontrez des problèmes pendant l'apprentissage, n'hésitez pas à demander à Labby. Donnez des commentaires après la session, et nous résoudrons rapidement le problème pour vous.
Tracer une DSP de base
Tout d'abord, nous allons tracer une DSP de base à l'aide de données aléatoires. Nous allons créer une série temporelle, ajouter du bruit, puis tracer la DSP à l'aide de la fonction psd de la bibliothèque matplotlib.mlab.
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.mlab as mlab
np.random.seed(19680801)
dt = 0.01
t = np.arange(0, 10, dt)
nse = np.random.randn(len(t))
r = np.exp(-t / 0.05)
cnse = np.convolve(nse, r) * dt
cnse = cnse[:len(t)]
s = 0.1 * np.sin(2 * np.pi * t) + cnse
fig, (ax0, ax1) = plt.subplots(2, 1)
ax0.plot(t, s)
ax1.psd(s, 512, 1 / dt)
plt.show()
Comparaison avec le code MATLAB équivalent
Nous pouvons comparer le code précédent avec le code MATLAB équivalent pour accomplir la même chose :
dt = 0.01;
t = [0:dt:10];
nse = randn(size(t));
r = exp(-t/0.05);
cnse = conv(nse, r)*dt;
cnse = cnse(1:length(t));
s = 0.1*sin(2*pi*t) + cnse;
subplot(211)
plot(t, s)
subplot(212)
psd(s, 512, 1/dt)
Tracer la DSP avec différents niveaux de remplissage avec des zéros
Ensuite, nous allons tracer la DSP avec différents niveaux de remplissage avec des zéros. Cela utilise l'ensemble de la série temporelle d'un coup.
dt = np.pi / 100.
fs = 1. / dt
t = np.arange(0, 8, dt)
y = 10. * np.sin(2 * np.pi * 4 * t) + 5. * np.sin(2 * np.pi * 4.25 * t)
y = y + np.random.randn(*t.shape)
fig, axs = plt.subplot_mosaic([
['signal','signal','signal'],
['zero padding', 'block size', 'overlap'],
], layout='constrained')
axs['signal'].plot(t, y)
axs['signal'].set_xlabel('temps [s]')
axs['signal'].set_ylabel('signal')
axs['zero padding'].psd(y, NFFT=len(t), pad_to=len(t), Fs=fs)
axs['zero padding'].psd(y, NFFT=len(t), pad_to=len(t) * 2, Fs=fs)
axs['zero padding'].psd(y, NFFT=len(t), pad_to=len(t) * 4, Fs=fs)
axs['block size'].psd(y, NFFT=len(t), pad_to=len(t), Fs=fs)
axs['block size'].psd(y, NFFT=len(t) // 2, pad_to=len(t), Fs=fs)
axs['block size'].psd(y, NFFT=len(t) // 4, pad_to=len(t), Fs=fs)
axs['block size'].set_ylabel('')
axs['overlap'].psd(y, NFFT=len(t) // 2, pad_to=len(t), noverlap=0, Fs=fs)
axs['overlap'].psd(y, NFFT=len(t) // 2, pad_to=len(t),
noverlap=int(0.025 * len(t)), Fs=fs)
axs['overlap'].psd(y, NFFT=len(t) // 2, pad_to=len(t),
noverlap=int(0.1 * len(t)), Fs=fs)
axs['overlap'].set_ylabel('')
axs['overlap'].set_title('superposition')
for title, ax in axs.items():
if title =='signal':
continue
ax.set_title(title)
ax.sharex(axs['zero padding'])
ax.sharey(axs['zero padding'])
plt.show()
Tracer la DSP d'un signal complexe
Enfin, nous allons tracer la DSP d'un signal complexe pour démontrer que les DSP complexes fonctionnent correctement.
prng = np.random.RandomState(19680801)
fs = 1000
t = np.linspace(0, 0.3, 301)
A = np.array([2, 8]).reshape(-1, 1)
f = np.array([150, 140]).reshape(-1, 1)
xn = (A * np.exp(2j * np.pi * f * t)).sum(axis=0) + 5 * prng.randn(*t.shape)
fig, (ax0, ax1) = plt.subplots(ncols=2, layout='constrained')
yticks = np.arange(-50, 30, 10)
yrange = (yticks[0], yticks[-1])
xticks = np.arange(-500, 550, 200)
ax0.psd(xn, NFFT=301, Fs=fs, window=mlab.window_none, pad_to=1024,
scale_by_freq=True)
ax0.set_title('Périodogramme')
ax0.set_yticks(yticks)
ax0.set_xticks(xticks)
ax0.grid(True)
ax0.set_ylim(yrange)
ax1.psd(xn, NFFT=150, Fs=fs, window=mlab.window_none, pad_to=512, noverlap=75,
scale_by_freq=True)
ax1.set_title('Welch')
ax1.set_xticks(xticks)
ax1.set_yticks(yticks)
ax1.set_ylabel('')
ax1.grid(True)
ax1.set_ylim(yrange)
plt.show()
Sommaire
Dans ce tutoriel, nous vous avons montré comment tracer la densité spectrale de puissance (DSP) à l'aide de la bibliothèque Matplotlib en Python. Nous avons commencé par tracer une DSP de base, puis l'avons comparée au code MATLAB équivalent. Nous avons ensuite tracé la DSP avec différents niveaux de remplissage avec des zéros, suivi de la tracé de la DSP d'un signal complexe.