libiir/python/filter_analysis.ipynb

176 lines
59 KiB
Plaintext
Raw Normal View History

{
"metadata": {
"name": "",
"signature": "sha256:5b0dafe7d37bc894511c97dd35f5e879105d8ec76b5947ed751b794510920348"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"Filter analysis test"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First configure the filter as desired. The filter is independent of sample rate, but is specified as a ratio to it. We use a specific value here simply to aid comprehension and label all the graph axes as desired. Setting it to 1 would be the same as specifying everything as a ratio."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import iir\n",
"\n",
"# change this to alter the sample rate we are displaying at\n",
"sample_rate = 100 # Hz\n",
"nyquist_freq = sample_rate / 2\n",
"\n",
"# build the filter object, fi, here\n",
"corner_freq = 10 # Hz\n",
"order = 4\n",
"fi = iir.Filter(\"butterworth_lowpass(%d, 1.0, %f)\" % (order, corner_freq / nyquist_freq))"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 69
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here we set up the plotting library and helper functions."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%matplotlib inline\n",
"import matplotlib.pyplot as plt\n",
"import pylab\n",
"\n",
"# number of points to plot on graphs (arbitrary)\n",
"num_points = 1000\n",
"\n",
"# helper function: calls the Filter.response() method on each member of the array\n",
"respfunc = pylab.vectorize(lambda f: fi.response(f/sample_rate))"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 70
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Linear Bode plot"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"freq = pylab.linspace(0, nyquist_freq, num_points)\n",
"resp = respfunc(freq)\n",
"\n",
"fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(10, 10), dpi=100)\n",
"\n",
"axes[0].plot(freq, abs(resp), 'r')\n",
"axes[0].set_xlabel('Frequency (Hz)')\n",
"axes[0].set_ylabel('Magnitude')\n",
"\n",
"axes[1].plot(freq, angle(resp), 'r')\n",
"axes[1].set_xlabel('Frequency (Hz)')\n",
"axes[1].set_ylabel('Phase (radians)')\n",
"axes[1].set_ylim([-pi, pi])\n",
"axes[1].set_yticks(linspace(-pi, pi, 9))\n",
"axes[1].set_yticklabels([\"-\u03c0\", \"-\u00be\u03c0\", \"-\u00bd\u03c0\", \"-\u00bc\u03c0\", \"0\", \"\u00bc\u03c0\", \"\u00bd\u03c0\", \"\u00be\u03c0\", \"\u03c0\"])\n",
"\n",
"None"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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\nAh6v9pzHgEGEyQNtgAHARw2o
"text": [
"<matplotlib.figure.Figure at 0x7fce9ce81e80>"
]
}
],
"prompt_number": 71
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Logarithmic Bode plot"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"freq = pylab.logspace(-3, log10(nyquist_freq), num_points)\n",
"resp = respfunc(freq)\n",
"\n",
"fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(10, 10), dpi=100)\n",
"\n",
"axes[0].plot(freq, 10 * log10(abs(resp)), 'r')\n",
"axes[0].set_xlabel('Frequency (Hz)')\n",
"axes[0].set_xscale('log')\n",
"axes[0].set_ylabel('Magnitude (dB)')\n",
"axes[0].axhline(y=-3)\n",
"\n",
"axes[1].plot(freq, angle(resp), 'r')\n",
"axes[1].set_xlabel('Frequency (Hz)')\n",
"axes[1].set_xscale('log')\n",
"axes[1].set_ylabel('Phase (radians)')\n",
"axes[1].set_ylim([-pi, pi])\n",
"axes[1].set_yticks(linspace(-pi, pi, 9))\n",
"axes[1].set_yticklabels([\"-\u03c0\", \"-\u00be\u03c0\", \"-\u00bd\u03c0\", \"-\u00bc\u03c0\", \"0\", \"\u00bc\u03c0\", \"\u00bd\u03c0\", \"\u00be\u03c0\", \"\u03c0\"])\n",
"\n",
"None"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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\nUUfSbuVsWn0dGEpI5GYCKwML
"text": [
"<matplotlib.figure.Figure at 0x7fce9d421ac8>"
]
}
],
"prompt_number": 72
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 34
}
],
"metadata": {}
}
]
}