Bode plot of DSP filter?

I designed a discrete Butterworth filter using the DSP package. How can I create a Bode plot of the transfer function?

using DSP

function create_filter(cut_off_freq; order=4, type=:Butter, dt)
    if type == :Butter
        return Filters.digitalfilter(Filters.Lowpass(cut_off_freq; fs=1/dt), Filters.Butterworth(order))
    elseif type == :Cheby1
        return Filters.digitalfilter(Filters.Lowpass(cut_off_freq; fs=1/dt), Filters.Chebyshev1(order, 0.01))
    end
end

dt = 0.05
cut_off_freq = 2.0 # Hz
butter = create_filter(cut_off_freq; order=4, dt)
using ControlSystemsBase, Plots
bodeplot(tf(butter))

3 Likes

Using only DSP.jl, you could do:

using DSP, Plots; gr()
default(fontfamily="Computer Modern", framestyle=:box, dpi=600)

w = range(1e-9, pi, 1024)
h = freqz(butter, w)

ws = (w/pi)*(0.5/dt)
p1 = plot(ws, 20*log10.(abs.(h)), xlims=(1e-2, 10), ylims=(-60, 6), xscale=:log10, xlabel="", ylabel="Magnitude (db)", label=false, title="2Hz Lowpass 4th-order Butterworth", lw=2, c=:blue, minorgrid=true)
p2 = plot(ws, 180/pi*unwrap(angle.(h)), xlims=(1e-2, 10), ylims=(-360, 6), xscale=:log10, xlabel="Frequency (Hz)",ylabel="Phase (deg)", label=false, lw=2, c=:red, minorgrid=true)
plot(p1, p2, layout=(2,1), size=(800, 800))

which produces:

3 Likes

Thanks! But there is a small mistake in your code,it must be:

tf(butter, dt)

with dt being the sampling time, otherwise the result is wrong.
I used this script to create this plot:

Thanks! Always good to have less package dependencies.

1 Like

Added minorgrid=true, which was an important omission for this type of logarithmic scale plots.