2

here I have plotted an ecg signal in time-domain and frequency-domain with fft(): time-domain

frequency-domain

but as you can see, the x-axis of both images are still in samples.

I have searched some references how to convert samples into time (s) and frequency (Hz), but it fails, not only the x-axis changes but also the plot shape.

Can you help me to solve this problem? Thank you.

Ngr Wisnu
  • 47
  • 1
  • 2
  • 9
  • To convert the x-axis in the time domain you should have the sample rate of the signal. The sample rate is the number of samples per second and as the definition says, you have to divide the number of samples you have in the signal by the sample rate. Then you get the temporal length of the signal. For the frequency domain, you have to give me more information how you converted the signal. – hamid.khb Aug 12 '21 at 12:41
  • you can also take a look at this [post](https://stackoverflow.com/questions/49439510/how-to-plot-fft-of-signal-with-correct-frequencies-on-x-axis) – hamid.khb Aug 12 '21 at 12:47
  • is sample rate the same as sample frequency? Because when I read the audio file using `Fs, data = read('input_ecg.wav')` and got the Fs value is 44100 Hz. I use this code to transform the time-domain into frequency-domain: `f_dom = np.abs(np.fft.fft(data))` – Ngr Wisnu Aug 12 '21 at 12:56
  • yes it is. and the inverse value of it is the timestep. you can use the length of the signal (signal.size) and the timestep to calculate the frequency bins using `np.fft.fftfreq(signal.size, d=timestep)`. Look up this [documentation](https://numpy.org/doc/stable/reference/generated/numpy.fft.fftfreq.html) – hamid.khb Aug 12 '21 at 13:03

2 Answers2

2

The Code can look like this:

signal, sample_rate = librosa.load(blues_1)
max_time = signal.size/sample_rate

time_steps = np.linspace(0, max_time, signal.size)
plt.figure()
plt.plot(time_steps, signal)
plt.xlabel("Time [s]")
plt.ylabel("Amplitude")

f = np.abs(np.fft.fft(signal))
freq_steps = np.fft.fftfreq(signal.size, d=1/sample_rate)
plt.figure()
plt.plot(freq_steps, f)
plt.xlabel("Frequency [Hz]")
plt.ylabel("Amplitude")

Time Domain

Frequency Domain

Understandably you can also plot only half of the values in frequency domain.

hamid.khb
  • 432
  • 2
  • 11
  • _Understandably you can also plot only half of the values in frequency domain._ is of course true, but only because you're calling the wrong function. Use `numpy.fft.rfft` instead. – Reinderien Jan 23 '23 at 17:21
0

A variation with Scipy

sample_rate, signal = scipy.io.wavfile.read( pathname1+file)
max_time = signal.size/sample_rate
time_steps = np.linspace(0, max_time, signal.size)
plt.plot(time_steps,signal)