digital Butterworth high pass filter

I am trying to high-pass filter a signal using a Butterworth filter, but I am getting the following results :

As in the picture, there is no signal decay.

python code:

import required modules
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
import math

# Specifications of Filter

# sampling frequency
f_sample = 70000

# pass band frequency
f_pass = 24000

# stop band frequency
f_stop = 16000

# pass band freq in radian
wp = (2*f_pass)/f_sample

# stop band freq in radian
ws = (2*f_stop)/f_sample

# pass band ripple
g_pass = 3

# stop band attenuation
g_stop = 40

# Conversion to prewrapped analog frequency
omega_p = 2*np.tan(wp/2) # (2*f_sample)*np.tan(wp/2)
omega_s = 2*np.tan(ws/2) # (2*f_sample)*np.tan(ws/2)

# Design of Filter using signal.buttord function
N, Wn = signal.buttord(omega_p, omega_s, g_pass, g_stop, analog=True)

# Printing the values of order & cut-off frequency!
print("Order of the Filter=", N) # N is the order
# Wn is the cut-off freq of the filter

# Conversion in Z-domain

# b is the numerator of the filter & a is the denominator
b, a = signal.butter(N, Wn, 'high', True)

# Filter a noisy signal.
T = 0.1
nsamples = T * f_sample
t = np.arange(0, nsamples) / f_sample
f0 = 18000.0
x = np.sin(2 * np.pi * f0 * t )
y = signal.lfilter(b, a, x)

plt.figure(1)
plt.clf()
plt.plot(t, x, label='Input signal')
plt.plot(t, y, label='Output signal')

plt.figure(2)
plt.clf()
w, h = signal.freqz(b, a, fs=f_sample, worN=2000)
plt.plot(w, abs(h), label="order = %d" % Wn)
plt.show()


I'm not sure what you're expecting to see?

• Your noisy signal (by the way, it's not noisy, it's a pure tone) is a sine wave at frequency $$18000\, \text{Hz}$$.
• Your filter has a stop-band $$f_{stop} = 16000\,\text{Hz}$$ and a pass-band $$f_{pass} = 24000\,\text{Hz}$$ so there's a transition band between $$f_{stop}$$ and $$f_{pass}$$ wherein lies your signal.

You're creating an analog filter with the frequency response that you plotted. Let's zoom in on that around the frequency of your input signal:

As you can see, your filter is actually amplifying your signal (by approximately $$20\log_{10}(1.33) = 2.5\,\text{dB}$$)

Did you mean to create a digital filter? in which case you'd want to change

# b is the numerator of the filter & a is the denominator
b, a = signal.butter(N, Wn, 'high', True)


to

# b is the numerator of the filter & a is the denominator
b, a = signal.butter(N, Wn, 'high', False)


• Yes, I meant everything I mentioned Thanks you verry mush, can you share with us the code that showed the last shape. Nov 18, 2022 at 17:06
• This is just a logarithmic view of the magnitude responses. plt.plot(w, 20*np.log10(abs(h)), label="order = %d" % Wn) for both analog and digital filters.
– Jdip
Nov 18, 2022 at 22:54