4

I have code that looks like this:

import matplotlib.pyplot as plt
import numpy as np
from nfft import nfft


# number of sample points
N = 400

# Simulated non-uniform data
x = np.linspace(0.0, 1 / 2, N) + np.random.random((N)) * 0.001
y = np.sin(50.0 * 2.0 * np.pi * x) + 0.5 * np.sin(80.0 * 2.0 * np.pi * x)
yf = np.abs(nfft(x, y))

fig, axs = plt.subplots(1)
fig_f, axs_f = plt.subplots(1)

axs.plot(x, y, '.', color='red')
axs_f.plot(x, yf, color='red')

graphs produced by code

How do I convert the values on the second graph to represent frequency?

The use of the nfft module is not required, answers using pynfft or scipy will be greatly appreciated.

See also: How do I obtain the frequencies of each value in an FFT?

Krish
  • 1,044
  • 9
  • 20
  • I think we have an answer for your question, check it out, see if it works for you, and let me know. – DrM Apr 07 '21 at 20:50
  • Tested and it works, thanks! – Krish Apr 08 '21 at 16:52
  • 1
    It case it might be of help, generally when I need a nonuniform transform, I just do the explicit FT, c.f. sum A_t e_{ i f t}, over all of the (A_t,t) in the data set , and iterate over the f of interest. Modern computers are often fast enough, and data sets are often small enough, that the "fast" in FFT is not so important. – DrM Apr 09 '21 at 19:40
  • Back then, I looked at the FFT (and to some extent still do) as a magic box that gets frequencies; A comment like that would have been a godsend. Thanks once again! – Krish Apr 09 '21 at 20:39
  • Another important comment would be to mention windowing. Any finite set of points has an implicit window. – DrM Apr 11 '21 at 01:09

1 Answers1

1

The following seems to work. Notice the line inserted before graphing the Fourier transform, to generate the frequencies, and that we graph N/2 of the data.

import matplotlib.pyplot as plt
import numpy as np
from nfft import nfft

# number of sample points
N = 400

# Simulated non-uniform data
x = np.linspace(0.0,0.5-0.02, N) + np.random.random((N)) * 0.001
print(x)

print( 'random' )
print( np.random.random((N)) * 0.001 )

y = np.sin(50.0 * 2.0 * np.pi * x) + 0.5 * np.sin(80.0 * 2.0 * np.pi * x)
yf = np.abs(nfft(x, y))

fig, axs = plt.subplots(1)
fig_f, axs_f = plt.subplots(1)

axs.plot(x, y, '.', color='red')

xf = np.fft.fftfreq(N,1./N)

axs_f.plot(xf[:int(N/2)], yf[:int(N/2)], color='red')

plt.show()

Output:

enter image description here

DrM
  • 2,404
  • 15
  • 29