# How to plot periodogram from DSP.jl?

**URL:** <https://discourse.julialang.org/t/how-to-plot-periodogram-from-dsp-jl/67969>\
**Category:** General Usage\
**Tags:** question, dates, dsp, nfft\
**Created:** [September 10, 2021, 5:26am UTC](https://discourse.julialang.org/t/how-to-plot-periodogram-from-dsp-jl/67969 "2021-09-10T05:26:16Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mdsa3d](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mdsa3d/32/20389_2.png) [@mdsa3d](https://discourse.julialang.org/u/mdsa3d)\
**Post date:** [September 10, 2021, 5:26am UTC](https://discourse.julialang.org/t/how-to-plot-periodogram-from-dsp-jl/67969/1 "2021-09-10T05:26:16Z")

</div>

I am trying to plot a periodogram for the following data. However, I am not sure how can i plot a periodogram object ?

Code:

```julia
#= DataFrame
10×10 DataFrame
 Row │ Date Open High Low Close Volume AdjustedOpen AdjustedHigh AdjustedLow AdjustedClose 
     │ Date Float64 Float64 Float64 Float64 Float64 Float64 Float64 Float64 Float64       
─────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1 │ 2020-08-21 41.3 41.34 40.71 41.01 2.55177e7 38.5015 38.5388 37.9515 38.2312
   2 │ 2020-08-24 41.28 42.5078 41.09 42.22 1.82089e7 38.4829 39.6275 38.3058 39.3592
   3 │ 2020-08-25 41.66 42.065 40.7 40.88 3.12856e7 38.8371 39.2147 37.9422 38.11
   4 │ 2020-08-26 40.64 40.835 40.0 40.01 2.6795e7 37.8862 38.068 37.2896 37.2989
   5 │ 2020-08-27 40.0 40.3 39.305 39.74 3.20343e7 37.2896 37.5693 36.6417 37.0472
   6 │ 2020-08-28 39.84 40.92 39.76 40.69 3.34771e7 37.1405 38.1473 37.0659 37.9329
   7 │ 2020-08-31 40.64 40.72 39.895 39.94 2.52596e7 37.8863 37.9608 37.1917 37.2337
   8 │ 2020-09-01 39.75 39.75 39.045 39.43 2.24782e7 37.0565 37.0565 36.3993 36.7582
   9 │ 2020-09-02 39.23 39.715 38.95 39.19 2.64134e7 36.5718 37.0239 36.3108 36.5345
  10 │ 2020-09-03 39.2 40.03 38.88 39.11 2.88172e7 36.5438 37.3176 36.2455 36.4599
=#
using DSP, DataFrames, Plots
data = df[:, :AdjustedClose]
a = periodogram(data)

```

Thanks look forward to the suggestions.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [September 10, 2021, 8:14am UTC](https://discourse.julialang.org/t/how-to-plot-periodogram-from-dsp-jl/67969/2 "2021-09-10T08:14:48Z")

</div>

[LPVSpectral.jl](https://github.com/baggepinnen/LPVSpectral.jl) defines plot recipes for periodograms and spectrograms

```julia
julia> using DSP, LPVSpectral

julia> plot(periodogram(randn(1000)))

```

 ![per](https://global.discourse-cdn.com/julialang/original/3X/9/8/98dc1eb5d198b15d5e7acdfedfe0527e7d4587e8.png)

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [September 10, 2021, 3:55pm UTC](https://discourse.julialang.org/t/how-to-plot-periodogram-from-dsp-jl/67969/3 "2021-09-10T15:55:34Z")

</div>

@mdsa3d, one difficulty with your input data is that the time axis has a non-uniform sampling rate, which is a requirement of the FFTW. I.e., the Date column in the dataframe is not sampled at a regular time interval.

Strictly speaking, [NFFT.jl](https://github.com/tknopp/NFFT.jl) or equivalent, should be used but AFAIK, there are no practical examples posted.

Code below using `NFFT.jl` was edited as well as example in post further down comparing `NFFT.jl` with `FINUFFT.jl`:

```julia
using Dates, DataFrames, NFFT, Statistics, Plots; gr()

colname = [:Date, :Open, :High, :Low, :Close, :Volume, :AdjustedOpen, :AdjustedHigh, :AdjustedLow, :AdjustedClose]

M =["2020-08-21" 41.3 41.34 40.71 41.01 2.55177e7 38.5015 38.5388 37.9515 38.2312;
     "2020-08-24" 41.28 42.5078 41.09 42.22 1.82089e7 38.4829 39.6275 38.3058 39.3592;
     "2020-08-25" 41.66 42.065 40.7 40.88 3.12856e7 38.8371 39.2147 37.9422 38.1100;
     "2020-08-26" 40.64 40.835 40.0 40.01 2.6795e7 37.8862 38.068 37.2896 37.2989;
     "2020-08-27" 40.0 40.3 39.305 39.74 3.20343e7 37.2896 37.5693 36.6417 37.0472;
     "2020-08-28" 39.84 40.92 39.76 40.69 3.34771e7 37.1405 38.1473 37.0659 37.9329;
     "2020-08-31" 40.64 40.72 39.895 39.94 2.52596e7 37.8863 37.9608 37.1917 37.2337;
     "2020-09-01" 39.75 39.75 39.045 39.43 2.24782e7 37.0565 37.0565 36.3993 36.7582;
     "2020-09-02" 39.23 39.715 38.95 39.19 2.64134e7 36.5718 37.0239 36.3108 36.5345;
     "2020-09-03" 39.2 40.03 38.88 39.11 2.88172e7 36.5438 37.3176 36.2455 36.4599]

df = DataFrame(M, colname)
df.Date = Date.(df.Date)
time = (df.Date .- df.Date[1]) ./ Day(1) # non-uniform days vector
data = Complex.(df.AdjustedClose)
md = mean(data)
n = size(df,1)

# normalize time span of 14 days over [-0.5, 0.5)
tnrm = range(-0.5,0.5,n+1)[1:n]
p = plan_nfft(tnrm, n)
g = nfft(p, data .- md)
freq = (-n÷2:n÷2-1)/time[end]

p1 = plot(time, Real.(data), xlabel="Day", ylabel="AdjustedClose")
p2 = plot(freq[n÷2+1:n], abs.(g)[n÷2+1:n], xlabel="1/Day", ylabel="Spectral amplitude",
           title="using NFFT.jl")
plot(p1,p2,legend=false, markershape=:circle, ms=2)

```

![NFFT_Type1](https://global.discourse-cdn.com/julialang/original/3X/8/1/81f624aec38b94b4af489504cacb5e6936355b59.png)

_ **NB:** depending on the actual problem, time interpolation + `FFTW.jl` might be enough._

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [September 12, 2021, 8:09pm UTC](https://discourse.julialang.org/t/how-to-plot-periodogram-from-dsp-jl/67969/4 "2021-09-12T20:09:33Z")

</div>

FWIW, please find below a practical example using [FINUFFT.jl](https://github.com/ludvigak/FINUFFT.jl), another Julia package for NFFT computations, with results compared to [NFFT.jl](https://github.com/tknopp/NFFT.jl).

The code uses Dates and days to be in line with OP’s problem of an irregularly sampled time series.

```julia
using Dates, FINUFFT, Statistics, Random, Plots; gr()

Random.seed!(111)

# INPUT DATA:
Tp = 365 # period domain
t = sort(Day.(rand(1:2Tp, 200))) ./ Day(1) # non-uniform days vector
st = 40 .+ sin.(2π*(3/Tp)*t) + cos.(2π*(7/Tp)*t) # data values
n = length(t) # number of points

# DATA PRECONDITION:
tn = range(-π,π,n+1)[1:n] # normalize to [-π,π)
st = Complex.(st) # complex data vector type required
M = 4*n # number of targets to compute the Fourier Transform

# COMPUTE (fast nufft of type-1):
tol = 1e-10
Ft = nufft1d1(collect(tn), st .- mean(st), +1, tol, M)
freq = (-M÷2:M÷2-1)/t[end]

# PLOT:
# The frequency peaks at 3/Tp (=0.008) and at 7/Tp (=0.019) are retrieved correctly:
p1 = plot(t, real(st), xlabel="Time (days)", ylabel="signal amplitude");
p2 = plot(freq[M÷2:M], abs.(Ft)[M÷2:M], xlabel="Frequency (1/day)", ylabel="Spectral amplitude",
          xlims=(0,0.05), title="using FINUFFT.jl");
plot(p1,p2,legend=false, markershape=:circle, ms=2)

# Compare to NFFT.jl. normalize time over [-0.5, 0.5):
# COMPUTE (fast nfft of type-1):
using NFFT
tn = range(-0.5,0.5,n+1)[1:n]
p = plan_nfft(tn, n)
Ft2 = nfft(p, st .- mean(st))
freq = (-n÷2:n÷2-1)/t[end]

# PLOT:
p1 = plot(t, Real.(st), xlabel="Day", ylabel="AdjustedClose")
p2 = plot(freq[n÷2+1:n], abs.(Ft2)[n÷2+1:n], xlabel="Frequency (1/day)", ylabel="Spectral amplitude",
          xlims=(0,0.05), title="using NFFT.jl")
plot(p1,p2,legend=false, markershape=:circle, ms=2)

```

The frequency peaks at 3/Tp (=0.008) and at 7/Tp (=0.019) are retrieved:

![FINUFFT_Type1_irregular_time_sampling](https://global.discourse-cdn.com/julialang/original/3X/8/2/820533c51ba10ae92492dfaa9a3d597d5c6c9fa1.png)

![NFFT_Type1_irregular_time_sampling](https://global.discourse-cdn.com/julialang/original/3X/6/7/67dcae2243b7c51f13922f030155681e7d91f8e0.png)

---

<div class="post-metadata">

**Author:** ![mdsa3d](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mdsa3d/32/20389_2.png) [@mdsa3d](https://discourse.julialang.org/u/mdsa3d)\
**Post date:** [September 13, 2021, 3:50pm UTC](https://discourse.julialang.org/t/how-to-plot-periodogram-from-dsp-jl/67969/5 "2021-09-13T15:50:26Z")

</div>

Thank you for this amazing suggestion, highly appreciate it!!!  
It has cleared numerous doubts for me !!!

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [September 19, 2021, 10:07am UTC](https://discourse.julialang.org/t/how-to-plot-periodogram-from-dsp-jl/67969/6 "2021-09-19T10:07:12Z")

</div>

Fyi, the code above was updated and in one of the posts a comparison is provided between `NFFT.jl` and `FINUFFT.jl` results.
