質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

1295閲覧

FFT分析を行い伝達関数グラフを作成する方法

tsuji__

総合スコア11

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/03/02 05:26

編集2021/03/02 07:19

前提・実現したいこと

初めての質問です。サンプリング周波数8192Hzのcsv形式波形ファイルをpythonで読み込みFFT分析を行い、横軸周波数 片振幅の伝達関数グラフの作成をしたいです。

発生している問題・エラーメッセージ

csvファイルにはがあり、それをコード内の条件で周波数分析を試みているのですが、クラスについての理解が疎いのか上手くコードが動作しません。以下のようなグラフが表示されてしまいます。
上から順に時刻歴波形 窓関数 伝達関数(デシベル表示)
イメージ説明

該当のソースコード

python

1import numpy as np 2import matplotlib.pyplot as plt! 3import csv 4from scipy import fftpack 5from scipy import signal 6F_s=[] 7path="Wave_Fs8192_01.csv" 8with open (path) as f: 9 for row in csv.reader(f, quoting=csv.QUOTE_NONNUMERIC): 10 F_s.append(float(row[0])) 11 12class TestFFT(): 13 14 def __init__(self): 15 self.msg = 'Wave_Fs8192_01.csv' 16 設定値 17 self.fs = 8192 # サンプリング周波数 18 self.N=4096 #サンプル数(フレームサイズ) 19 self.fmax=8192/2.56 #最大周波数 20 self.line=400#ライン数 21 self.sec = self.line/self.fmax # 時間 22 self.start_time = 2.25 # 抽出開始時間 23 self.period = 1/self.fs # 抽出期間 24 25 26 オーバーラップの関数 27 def ov(self, F_s, Fc, overlap): 28 overlap=50 29 Ts = len(F_s) / self.fs #データ長 30 Fc = self.N / self.fs#フレーム周期 31 x_ol = self.fs * (1 - (overlap/100)) 32 N_ave = int((Ts - (Fc * (overlap/100))) / (Fc * (1-(overlap/100)))) 33 34 array = [] 35 36 for i in range(N_ave): 37 ps = int(x_ol * i) 38 array.append(F_s[ps:ps+self.fs:1]) 39 return array, N_ave 40 41 def process(self): 42 43 print(self.msg) 44 t=np.arange(0,self.sec,self.period) 45 46 start=int(self.start_time*self.fs) 47 end=int(self.start_time + self.period)*self.fs 48 y=F_s[start:end] 49 x=t[start:end] 50 51 fft(y,self.fs) 52 53 54 plt.show() 55 56def fft(array, fs, ylabel_name='Data', xlabel_name='Time'): 57 58 窓関数で波形を切り出す 59 L = len(F_s) 60 61 window=signal.boxcar(L) 62 array_window = F_s * window 63 64 FFT計算 65 66 NFFT = 2**nextpow2(L) 67 fft_amp = fftpack.fft(array_window, NFFT) 68 fft_fq = fftpack.fftfreq(NFFT, d=1.0/fs) 69 70 fft_amp = fft_amp[0: int(len(fft_amp)/2)] 71 fft_fq = fft_fq[0: int(len(fft_fq)/2)] 72 fft_amp = db(abs(fft_amp)) 73 74 75 plt.figure(figsize=(8, 6*1.5)) 76 plt.subplots_adjust(hspace=0.4) 77 78 plt.subplot(3, 1, 1) 79 plt.plot(F_s) 80 plt.ylabel(ylabel_name) 81 plt.grid() 82 83 plt.subplot(3, 1, 2) 84 plt.plot(array_window) 85 plt.xlabel(xlabel_name) 86 87 plt.ylabel('Data*hann') 88 plt.grid() 89 90 plt.subplot(3, 1, 3) 91 plt.plot(fft_fq, fft_amp) 92 plt.xlim(0, fs/2) 93 plt.xlabel('Frequency [Hz]') 94 plt.ylabel('Amplitude [dB]') # |X(omega)| 95 plt.grid() 96 97 98def nextpow2(n): 99 m_f = np.log2(n) 100 m_i = np.ceil(m_f) 101 return int(np.log2(2**m_i)) 102 103 104def db(x, dBref=1): 105 y = 20 * np.log10(x / dBref) 106 return y 107 108 109if __name__ == '__main__': 110 proc = TestFFT() 111 proc.process()

試したこと

ネットでサンプルコードをもとにpythonの実行順番 デバッグなどを試み、クラス selfなどは一通り独学で学習し、実際に試したりもしました。

補足情報(FW/ツールのバージョンなど)

初めての質問でまだ使い勝手がよく分かっておらずソースコードなど見にくいと思いますがご容赦ください。
お手数ではございますが、teratailさんにコードを記述する際のアドバイス等一言だけでもございましたら、書いていただけると嬉しいです。本筋とは離れた要求であることは承知しておりますがどうかよろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TakaiY

2021/03/02 06:19

この状態ではソースが読めないので、ソースコードの貼り付けの作法に従った書き方に修正してください。
jbpb0

2021/03/02 06:59

pythonのコードの一番最初の行のすぐ上に ```python だけの行を追加してください また、pythonのコードの一番最後の行のすぐ下に ``` だけの行を追加してください 現状、コードがとても読み辛いです 質問にコードを載せる際に上記をやってくれたら、他人がコードを読みやすくなり、コードの実行による現象確認もやりやすくなるので、回答されやすくなります
jbpb0

2021/03/02 13:53 編集

グラフに表示させるデータ数が多すぎて、隙間がなくなってしまっているのだと思います plt.plot(F_s) を、たとえば plt.plot(F_s[0:300]) みたいに変えて、先頭の一部だけグラフに表示させたら、データの形が現れませんでしょうか? ただし、「300」は適当なので、いろいろ変えてみてください あと、「scipy.signal.boxcar()」は全部1.0だから、それを掛けてもデータは変わらないため、「array_window」は「F_s」と同じです
jeanbiego

2021/03/03 00:32

データのCSVか、あるいはダミーデータは用意できますか? データがないとテストもできないため、数行程度のコードでもない限りは回答がつきづらいと思います。 また、コメントは正しくコメントアウトしておいてください。
guest

回答1

0

グラフに表示させるデータ数が多すぎて、隙間がなくなってしまっているのだと思います

python

1plt.plot(F_s)

を、たとえば

python

1plt.plot(F_s[0:300])

みたいに変えて、先頭の一部だけグラフに表示させたら、データの形が現れると思います
ただし、「300」は適当なので、いろいろ変えてみてください

あと、「scipy.signal.boxcar()」は全部1.0だから、それを掛けてもデータは変わらないため、「array_window」のグラフは「F_s」のグラフと同じです
(窓関数の種類を変えたら、グラフは当然変わります)

投稿2021/03/15 07:55

jbpb0

総合スコア7651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問