Wizard Notes

Python, JavaScript を使った音楽信号分析の技術録、作曲活動に関する雑記

Python:matplotlibで双二次フィルタの極・零点をプロット

自作の双2次フィルタ (Biquad Filter)のPythonライブラリ PyQuadFilter に極と零点をプロットする関数を実装しました。

exmamples/04_plot_pole_zero.pyがサンプルコードとなっています。

プロット例

オールパスフィルタの極/零点プロットです。

  • q = 1.5
  • fc = 1000

零点と極がオールパスフィルタの特徴的な配置となっていることを確認できます*1

プロット用関数のソースコード

係数多項式の解はnp.rootsで求めています。

def plot_pole_zero(b, a):
    max_v = 1.0
    def plot_comp(c, label, color, marker, _max_v):
        x, y = np.real(c), np.imag(c)
        plt.plot(x, y, marker=marker, color=color, label=label)
        _max_v = np.abs(x) if np.abs(x) > _max_v else _max_v
        _max_v = np.abs(y) if np.abs(y) > _max_v else _max_v
        return _max_v
        
    plt.figure(figsize=(6, 6))
    theta = np.linspace(0, 2*np.pi, 360)
    plt.plot(np.cos(theta), np.sin(theta), c="black", linestyle="dotted")
    plt.grid()
    
    zeros, poles = np.roots(b), np.roots(a)
    max_v = plot_comp(zeros[0], "zero 0", "b", "x", max_v)
    max_v = plot_comp(zeros[1], "zero 1", "b", "x", max_v)
    max_v = plot_comp(poles[0], "pole 0", "r", "o", max_v)
    max_v = plot_comp(poles[1], "pole 1", "r", "o", max_v)
    max_v *= 1.1
    plt.xlim(-max_v, max_v)
    plt.ylim(-max_v, max_v)
    plt.xlabel("Real")
    plt.ylabel("Imag")
    plt.legend(bbox_to_anchor=(1, 0), loc='lower right')

*1:振幅応答が1になるため、分子と分母の振幅応答が打ち消しあう