blogソフトウェア開発と人生をやっていきますこの広告は、90日以上更新していないブログに表示しています。-Matplotlibのxkcd関数とFIRフィルタ-PythonPythonのグラフ描画ライブラリのMatplotlibには、手書き風のグラフを描画するための関数xkcd()があります。以下のソースコードを実行すると、手書き風のsinグラフが描画されます。graph')plt.show()温かみがあっていい感じですね。このような手書き風グラフは、関数の名前にも使われているxkcdというサイトの画像をリスペクトしたものです。Pattern理系的なネタが多く、エンジニアの間でもよく話題になります。いったテイストの本、ホワット・イフが翻訳されて話題になりました。見るさて、このような手書き風グラフはコンピュータでどのように描画しているのでしょうか?乱数生成とローパスフィルタ現在Matplotlibに実装されているxkcd()関数の原案となったブログ記事を参考にしながら読み解いて行きます。Perambulations記事のxkcd_line()に注目してください。y)を与えたときに、その間を補間するための点を生成します。補完する点にノイズ(ゆらぎ)を加えることによって、手書きのようなガタガタとした線を表現することができます。この線を描画するために、補間する点数の制御やB-Spline曲線での近似などの様々な工夫がされていますが、肝となる部分はFIRフィルターのローパスフィルタによるノイズ制御と言って問題ないと思います。*2xkcd_line()中の次のコードを見てみましょう。coeffs)1行目のコードは線に加えるノイズの大きさを決めています。magを変化させることによって乱数のスケールが変化し、線のガタツキの強弱が変わります。2行目のコードではFIRフィルタでローパスフィルタの設計を行っています。(FIRフィルターについては後述します)ローパスフィルタは低周波成分のみを通過させて、高周波成分をカットするフィルタです。1行目で生成した乱数の中で、しきい値を超えたものを0にする処理を行います。これにより本来のグラフから極端に外れた点を抑制することができるので、適度なガタツキを表現することができます。3行目のコードでは、2行目で設計したローパスフィルターを実際に適応しています。Filter)とも呼ばれるディジタルフィルタの一種です。FIRフィルターの回路は次の図と式で表されます。$$x[n]を入力信号、y[n]を出力、b[n]をフィルタ係数とします。このとき上式のNを一般にタップ数と呼びます。このフィルタに入力x[n]を入れたときに必要のない周波数成分を取り除くように回路を設計することによって、ローパスフィルタやハイパスフィルタを実現することができます。この式から、タップ数を増やすことで入力に対して大きな応答を得ることができることがわかります。xkcd_line()内で使われいるscipyに実装されているFIRフィルターsignal.firwin()は、第1引数にカットオフ周波数、第2引数にタップ数、第3引数に窓関数を指定する仕様になっています。9]として、タップ数とカットオフ周波数を変更していきながらグラフの結果を見ていきます。タップ数の係数を大きくするに従って波の振動が細かくなっていることがわかります。ここで注意したいのは変更した値はタップ数の「係数」で、タップ数そのものではありません。計算しておいた補間する点の2点間距離に係数をかけています。カットオフ周波数を大きくするにしたがって、波の振動が抑えられていることがわかります。人工知能に関する断創録*1:私もこの本を読みましたが、とてもおもしろかったです*2:他にもフォントの変更など、Matplotlibに実装されているxkcd()関数はもっと凝った処理をしています*3:窓関数の特性に応じて、信号の解析することのできる範囲を変更することができます。»プロフィールid:drilldripperプログラミングと将棋が好きです。(1)月別アーカイブはてなブログをはじめよう!drilldripperさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。