3D Power-Spektrum Plot eines Sinussignals

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Benutzeravatar
RN710
User
Beiträge: 2
Registriert: Samstag 4. Februar 2023, 15:57
Wohnort: Bayern

Guten Abend alle zusammen,

im Rahmen einer wiss. Arbeit ist es meine Aufgabe das Power-Spektrum (Amplitudenspektrum in Dezibel [dB]) eines Sinussignals zu erstellen und zu speichern (.CSV). Das ganze aber 3-dimensional über die Zeit. Um mich der Korrektheit meines Codes zu vergewissern, möchte ich das ganze auch in einem 3D Diagramm (x-Achse: Frequenzbereich [Hz]; y-Achse: Zeit; z-Achse: Power-Spektrum [dB]) plotten. Dazu habe ich auch eine Orientierung vom Professor bekommen (siehe Bild).
2 Dimensional ist das alles kein Problem nur beim 3 dimensionalen tue ich mich schwer.

Bild

Was ich erreichen will:
  • x-Achse von -x1 bis +x1 Hertz (z.B -250Hz bis +250Hz)
  • liegt meine Frequenz bei konstanten 100Hz möchte ich das an der Stelle der Peak erscheint und dann wie eine senkrechte Ebene im Diagramm liegt (parallel zur y-z-Achse)
  • steigt oder sinkt die Amplitude möchte ich das sich dementsprechend die Höhe des Peaks verändert (Das sollte es auch bei einem Power-Spektrum)
  • zwecks Rechenaufwand soll die Berechnung abschnittsweise erfolgen (10sec Zeitfenster) worüber dann der Wert gemittelt wird
  • später müssen es dann auch 50.000 Abtastungen pro Sekunde sein, was zu einem hohen Speicherbedarf führt (erstmal irrelevant aber daher die Zeitfenster)
Lösen möchte/tue ich das mit:
  • np.fft.fft()
  • for-Schleife
  • plot.surface
Wo es hakt:
  • mein geplottetes Spektrum ist konstant trotz quadratisch zunehmender Amplitude
  • vermute das Problem liegt an dem letzten Array mit dem gemittelten Werten
Hinweis: Ich habe bereits in viele Richtungen das ganze versucht zu lösen. Ich beschränke mich hier aber auf das bisher "erfolgreichste"

Hier mein Code:

Vorgeplänkel/Definitionen:

Code: Alles auswählen

import matplotlib.pyplot as plt
import numpy as np

# Signal-Parameter
    #Form ax²+bx+b
a = 1
b = 1
c = 10
traegerfrequenz = 100 #in Hertz

# Funktions-Parameter
sample_rate = 200 #Abtastpunkte pro Sekunde
total_time = 100 #in Sekunden
zeitfenster_size = 10 #in Sekunden
total_samples = sample_rate * total_time #Abtastpunkte insgesamt
window_number = int(total_time/zeitfenster_size)
samples_zeitfenster = int(total_samples/window_number) #Abtastpunkte pro Zeitfenster

# Berechnung Zeit
time = np.linspace(1, total_time, total_samples, dtype=np.int32)
Schleife und Berechnung:

Code: Alles auswählen

# Zeitfenster-Schleife + Berechnung
powerspektrum_signal = []
gemittelt = []

for i in range(window_number):
    start_index = i * samples_zeitfenster
    end_index = start_index + samples_zeitfenster

    #Amplitudenberechnung für jedes Fenster
    amp = a * time[start_index:end_index] * time[start_index:end_index] + b * time[start_index:end_index] + c
    print("AMPLITUDE: ", amp) #Überprüfung

    #Signalberechnung
    signal = amp * np.sin(2*np.pi * traegerfrequenz * time[start_index:end_index])
    print("SIGNAL: ", signal) #Überprüfung

    #Fourier Transformation
    fourier_transform = np.fft.fft(signal)
    print("FFT_VALUES: ", fourier_transform) #Überprüfung

    #Power-Spektrum Berechnung + dB Umwandlung
    fourier_abs = np.abs(fourier_transform)
    Power_Spektrum_dB = 20 * np.log10(fourier_abs)
    print("dB_VALUES: ", Power_Spektrum_dB) #Überprüfung

    #Mitteln
    mittelwert_dB = np.mean(Power_Spektrum_dB)
    print("MITTELWERTE: ", mittelwert_dB) #Überprüfung

    #Überführung in Array
    gemittelt.append([mittelwert_dB])

#Umwandlung
gemittelt = np.array(gemittelt)
print("FINAL_VALUES: ", gemittelt)
Plotting

Code: Alles auswählen

#3D Plot
plt.figure()
ax = plt.axes(projection='3d')
ax.set_xlabel('Frequenz [Hz]')
ax.set_ylabel('Zeit [s]')
ax.set_zlabel('dB')
ax.set_title('Powerspektrum')

ax.plot_surface(traegerfrequenz, time, gemittelt)
plt.show()
Ich danke für jede Hilfe und Bemühung!

Grüße
Profilbild von Alicia Mathieu
Link: https://www.artstation.com/artwork/W9DN3
Antworten