Frequency response plots are often shown with *normalized frequency* on the X-axis. This sometimes confuses people. Figure 1 shows the frequency response of a typical low-pass filter, taken from the article How to Create a Simple Low-Pass Filter.

In this illustration, the range of the normalized frequency is [0, 0.5]. The normalized frequency is computed by dividing the true frequency by the sampling rate. Hence, the sampling rate itself has a normalized frequency of one. However, a digital signal can only uniquely represent frequencies up to half the sampling rate (the *Nyquist frequency*), which makes the practical limit 0.5. Many people might argue that the plots in Figure 2 are easier to interpret (the difference is in the scale of the X-axis).

And many people might be right. The second pair of plots shows the frequency response of the filter for a sampling rate of 10 kHz. This makes the cutoff frequency of the filter, which is 1 kHz, immediately clear. However, the danger is that a graph like this could be interpreted as “this filter removes frequencies above 1 kHz”, while the correct interpretation is “*at a sampling rate of 10 kHz*, this filter removes frequencies above 1 kHz”. In practice, a digital filter is applied to a series of numbers, and the sampling rate at which these numbers were acquired is nowhere in sight. If, for example, the filter from Figure 2 would be applied to a signal that was sampled at 20 kHz, the cutoff point of the filter would quietly change to *2* kHz.

Hence, it is more logical and less confusing to use the first pair of graphs instead, where only the normalized frequency is shown. So, if you read articles such as How to Create Simple Band-Pass and Band-Reject Filters, apply them to the problem at hand by multiplying the normalized frequency with the sampling rate to get the practical effect of the filter.

Tom,

Thanks for the filter design tools. Very handy ! (and very elegant)

I have to filter a barometric presssure series and it works very well.

Had a small problem with the Python code, Seems 2.7 doesn't force fL etc to float. Easy to fix but took a lot longer to figure it out that it should have.

Thanks again !

Jim

Thanks for your kind words! Also thanks for reporting the problem with the code if you use Python 2. I use Python 3 for everything, but I really should have put that in a comment in the code. I will adapt it. This is the result of the dreaded Python 2 division operator implementation… Adding “

`from __future__ import division`

” add the top of your script avoids these kinds of problems.(For people just reading the article above, these comments refer to the filter design tool at fiiir.com.)

## Add new comment