# 3d power spectrum of an sinus signal

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!