2013年3月20日水曜日

Matplotlibのグラフテンプレート

概要

matplotlibを使い出してからしばらく立ち,グラフの整形を一括して行いたいと思うようになった.
つまり,グラフ作成過程と,整形過程を分離してたスクリプトを書きたいと考えた.
そこで,テンプレートの設定方法について調べたところ,rcParamsを書き換えれば良いということが分かった.具体的にはここに全て書いてあるので,自分に必要な物を選択して変更すれば良い.
上記のページを元に自分用の仮テンプレートを作成したので上げておく.
こんな感じのグラフを作成する
グラフ軸に分数を使うよう設定するのがちょっと面倒


テンプレートのフォント周りについて

rcParamsの設定ではTex形式出力に利用するフォントとして通常文字に使用しているフォントの選択が可能であるようだ.
Tex形式のデフォルトはTexの数式で使われるフォントはそのままではIllustratorで利用できない.
まあ,Illustratorの設定を弄っても良いのだが,面倒くさいし,フォントを統一しておいたほうが便利かもしれないのでテンプレートではギリシャ文字出力に通常文字を割り当てるようにしている
これにより,ギリシャ文字出力が格段に楽になった(ユニコード調べるの面倒くさすぎ).

rcParamsの限界

rcParamsを使うことで相当細部までグラフの設定ができるが,実現したかった機能の内,幾つかは設定できなかったり,問題があった.(もしくは設定項目を適切に見つけることができなかった)
  1. グラフのマーカー自動設定
  2. 凡例のグラフ外部への配置設定
  3. 凡例の要素の列数設定
  4. Tex形式で分数を使った場合のサイズ縮小化対策
  5. EPSへのtype42フォント埋め込み設定(設定項目はあったがバグが生じた)
  6. マーカーをグラフ外枠より上に表示する方法(イラレでPDFを覗いた感じでは難しそう)
  7. TexフォントにSymbolフォントを利用する方法
  8. 文字列の配置を中揃えにする方法(軸で分数を使う際に軸ごとに設定できると便利)
上記以外にも幾つか問題点があったような気がする.
とりあえずEPSのフォント埋め込みに関連してXPDFはそのうち調べておく予定.

テンプレート



2013年3月18日月曜日

ScipyのFFTテスト

概要

Scipyには様々な科学技術計算用のツールが揃っている。
今回、その中の一つ、FFTを利用したサンプルコードを作成した.
具体的にはノイズの乗ったサンプルデータを作成し,これに対してFFTを行った後,高周波成分を除去し逆FFTを行う.

コード

以下の通り

import numpy as np
from scipy import fftpack #for fft
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rcParams['figure.autolayout']=True #グラフのはみ出しを回避するためのコマンド
mpl.rcParams['axes.grid']=True
#データ点数
num = 1000
#時間の最小値と最大値
tscale = (0.0, 4.0)
#x = 0, 001, 0.02, ..., 4.99, 5.00
t = np.linspace(tscale[0],tscale[1], num)
#元のデータ:今回は正弦波
y = np.sin(np.pi*t)
#ノイズの入ったデータ.実際のデータにはノイズが乗ることが多い
yn = y + np.random.normal(scale=1,size=num)
#元データとノイズの乗ったデータをプロットする.
plt.subplot(311)#今回3つのグラフを立てに並べるのでサブプロットを使う
plt.plot(t,yn, color='b', linewidth=2, label="raw")
plt.plot(t,y, color='r', linewidth=1, label='ideal')
plt.xlabel("time [s]")
plt.ylabel("Value")
plt.legend(loc=1,fancybox=True)
#上記のデータをFFTしたもの
freq = fftpack.fftfreq(num, ((tscale[1]-tscale[0])/num))
fftY = fftpack.fft(y)
fftYN = fftpack.fft(yn)
plt.subplot(312)
plt.plot(freq[np.where(freq>=0)],np.abs(fftYN)[np.where(freq>=0)],\
         color='b', linewidth=2, label="raw")
plt.plot(freq[np.where(freq>=0)],np.abs(fftY)[np.where(freq>=0)],\
         color='r', linewidth=1, label="ideal")
plt.xlabel("Freq [Hz]")
plt.xlim(0,128)
plt.legend(loc=1,fancybox=True)
#2Hz以上をカットして逆FFT
fftYN[np.where(freq>=1.)] = 0
fftYN[np.where(freq<-1.)] = 0
yn = fftpack.ifft(fftYN)
plt.subplot(313)
plt.plot(t,yn, color='b', linewidth=2, label="ifft")
plt.plot(t,y, color='r', linewidth=1, label='ideal')
plt.xlabel("time [s]")
plt.ylabel("Value")
plt.legend(loc=1,fancybox=True)
plt.savefig("scipyffttest.png", dpi=300)
plt.show()