Hello everyone!
within the scope of a scientific work. My task is to create and save the power spectrum (amplitude spectrum in decibel [dB]) of a sinusoidal signal (.CSV). But the whole thing 3-dimensional over the time. To make sure that my code is correct, I also want to plot the whole thing in a 3D diagram (x-axis: frequency range [Hz]; y-axis: time; z-axis: power spectrum [dB]). For this I also got an orientation from the professor (see picture).
2 dimensional is no problem, only 3 dimensional is difficult for me.
What I want to achieve:
-
x-axis from -x1 to +x1 Hertz (e.g. -250Hz to +250Hz)
-
if my frequency is at constant 100Hz I want the peak to appear at that point and then lie like a vertical
-
plane in the diagram (parallel to the y-z-axis)
-
if the amplitude increases or decreases I want the height of the peak to change accordingly (this should also be the case with a power spectrum)
-
for the sake of computational effort the calculation should be done section by section (10sec time window) over which the value is then averaged
-
later there must be 50.000 samples per second, which leads to a high memory requirement (irrelevant at first, but therefore the time windows)
I want/do to solve this with:
-
np.fft.fft()
-
for loop
-
plot.surface
Where it hangs:
-
my plotted spectrum is constant despite quadratic increasing amplitude
-
guess the problem is the last array with the averaged values
Note: I have already tried to solve this problem in many directions. I limit myself here however to the “most successful” one so far
Here is my code:
Definitions etc.
# 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)
calculation
# 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
#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()
Thanks to everyone who wants to help!