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

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

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

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

Q&A

解決済

1回答

1843閲覧

【python】連続ウェーブレット変換の縦軸目盛のずれについて

loss

総合スコア1

Python

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

0グッド

0クリップ

投稿2022/05/30 08:27

前提

pythonを勉強し始めた駆け出し学生です。
pythonで連続ウェーブレット変換をしようと試みています。
参考にさせていただいたサイトのコードにおいて、実行結果の縦軸目盛の表示にずれが生じています。
用意した波の周波数は2[Hz]、7[Hz]、13[Hz]であり、図のy軸の値に1ずつ足さなければplotしたい値(2、7、13)にならない状態です。
(参考サイトhttps://camedphone.com/archives/729#comment-288)

実現したいこと

  • 縦軸目盛の本来の値の表示をしたい

イメージ説明

該当のソースコード

python

1import numpy as np 2import matplotlib.pyplot as plt 3import math 4 5width = 6 6 7# マザーウェーブレット:モルレーウェーブレット 8def morlet(x, f, width): 9 sf = f / width 10 st = 1 / (2 * math.pi * sf) 11 A = 1 / (st * math.sqrt(2 * math.pi)) 12 h = -np.power(x, 2) / (2 * st**2) 13 co1 = 1j * 2 * math.pi * f * x 14 return A * np.exp(co1) * np.exp(h) 15 16# 連続ウェーブレット変換 17def mycwt(Fs, data, fmax, wavelet_R=2): 18 # Fs: サンプリング周波数 19 # data: 信号 20 # wavelet_R: マザーウェーブレットの長さ(秒) 21 # fmax: 解析する最大周波数 22 23 Ts = 1 / Fs # サンプリング時間幅 24 data_length = len(data) # 信号のサンプル数を取得 25 26 # マザーウェーブレットの範囲 27 wavelet_length = np.arange(-wavelet_R, wavelet_R, Ts) 28 29 # 連続ウェーブレット変換後のデータを格納する配列の作成 30 wn = np.zeros([fmax, data_length]) 31 32 # 連続ウェーブレット変換の実行 33 for i in range(0, fmax): 34 wn[i,:] = np.abs(np.convolve(data, morlet(wavelet_length, i+1, width), mode='same')) 35 wn[i,:] = (2 * wn[i, :] / Fs)**2 36 37 return wn 38 39# 連続ウェーブレット変換後のカラーマップ作成関数 40def cwt_plot(CWT, sample_time, fmax, fig_title): 41 plt.imshow(CWT, cmap='jet', aspect='auto',vmax=abs(CWT).max(), vmin=-abs(CWT).max()) 42 plt.title(fig_title) 43 plt.xlabel("time[ms]") 44 plt.ylabel("frequency[Hz]") 45 plt.axis([0, len(sample_time), 0, fmax-1]) 46 plt.colorbar() 47 48 49if __name__ == "__main__": 50 # 信号作成 ---------------------------------------- 51 Fs = 1000 # サンプリング周波数 52 Ts = 1 / Fs # 1ステップあたりの時間幅 53 time_S = 5 # 信号は5秒分 54 t_data = np.arange(0,time_S, Ts) # 5秒分の時間配列 55 f1, f2, f3 = 2, 7, 13 # 2[Hz], 7[Hz], 13[Hz]の信号 56 57 58 59 # signal作成 ---------------------------------------- 60 amp = np.linspace(0.5, 2, num = Fs* time_S) # 増幅用 61 62 ss01 = np.sin(2*np.pi*f1*t_data)* amp 63 ss02 = np.sin(2*np.pi*f2*t_data) 64 ss03 = np.sin(2*np.pi*f3*t_data)* np.flipud(amp) 65 66 signal = ss01 + ss02 + ss03 # 3つの信号の合成信号 67 68 # 連続ウェーブレット変換 ---------------------------------------- 69 fmax=20 # 解析する最大周波数 70 cwt_signal = mycwt(Fs=Fs, data=signal, fmax=fmax) 71 72 73 # signalの図 74 plt.figure() 75 plt.title("signal") 76 plt.plot(t_data, signal) 77 plt.xlabel("time[s]") 78 79 80 81 # signal02を連続ウェーブレット変換した時のカラーマップの図 82 plt.figure() 83 fig_title02 = "cwt signal" 84 cwt_plot(cwt_signal, t_data, fmax, fig_title02) 85 86 plt.show()

試したこと

軸ラベルの修正で色々検索し、下記のようなコードを試したのですがエラーも出てしまい、pythonの理解もあまり深くなく、進展が無い状況です。

from typing import List, Tuple def get_ticks_label_set(all_labels:List, num:int)-> Tuple[List, List]: length = len(all_labels) step = length//(num-1) pick_positions = np.arange(0, length, step) pick_labels = all_labels[::step] return pick_positions, pick_labels x_positions, x_labels = get_ticks_label_set(t, num=10) print(x_positions) print(x_labels) y_positions, y_labels = get_ticks_label_set(freqs[::-1], num=10) print(y_positions) print(y_labels)

python初心者のため色々なサイトを参考にしながらプログラムを改良しようと試みたのですが、うまくいかず困っています。
ご教授お願いいたします。

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

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

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

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

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

jbpb0

2022/05/31 22:44 編集

「def mycwt(...」の wn[i,:] = np.abs(np.convolve(data, morlet(wavelet_length, i+1, width), mode='same')) で「i+1」としてるので、たとえば「wn[0,:]」には「周波数1」の結果が入ります そこのforループを for i in range(1, fmax): と変えて、「morlet(wavelet_length, i, width)」とすれば、たとえば「wn[1,:]」に「周波数1」の結果が入るようになり、縦軸と合うと思います
loss

2022/06/01 00:01

ありがとうございます。 見事に解決することができました! pythonに慣れてきたと思っていたのですが、まだまだでした・・・プログラミングでは0から数えるということを改めて認識することができました。 より能力の向上に努めようと思います。この度はありがとうございました。
guest

回答1

0

ベストアンサー

「def mycwt(...」の

python

1 wn[i,:] = np.abs(np.convolve(data, morlet(wavelet_length, i+1, width), mode='same'))

で「i+1」としてるので、たとえば「wn[0,:]」には「周波数1」の結果が入ります

 
そこのforループを

python

1 for i in range(1, fmax):

と変えて、「morlet(wavelet_length, i, width)」とすれば、たとえば「wn[1,:]」に「周波数1」の結果が入るようになり、縦軸と合うと思います

投稿2022/07/29 08:17

jbpb0

総合スコア7651

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問