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

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

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

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

Q&A

解決済

1回答

6438閲覧

ピーク検出後その値を用いてピークフィッティングをしたいです

Nari9113

総合スコア3

Python

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

0グッド

0クリップ

投稿2021/12/01 04:40

編集2021/12/02 11:52

前提

あるデータを用いて①ピーク検出②その検出した値からピークフィッティングを用いてピークを求めるのを一つにまとめたいです
色々サイトを見て進めているのでごちゃごちゃしていると思うので省略できそうな部分があればそれも教えて頂きたいです

実現したいこと

①で出たx[maxid],y[maxid]を②のx1,y1に一つずつ自動入力され値が得られるような自動解析ができるコードを作りたいです

###追記部分エラーメッセージ

Python

1RuntimeError Traceback (most recent call last) 2C:\Users\Public\Documents\Wondershare\CreatorTemp/ipykernel_9180/2660802360.py in <module> 3 88 guess_total.append(background) 4 89 5---> 90 popt, pcov = curve_fit(func, x, y, p0=guess_total) 6 91 7 92 8 9~\AppData\Local\Programs\Python\Python39\lib\site-packages\scipy\optimize\minpack.py in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs) 10 792 cost = np.sum(infodict['fvec'] ** 2) 11 793 if ier not in [1, 2, 3, 4]: 12--> 794 raise RuntimeError("Optimal parameters not found: " + errmsg) 13 795 else: 14 796 # Rename maxfev (leastsq) to max_nfev (least_squares), if specified. 15 16RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 14200.

補足情報

もし必要な情報があればコメントお願いします。助けてください泣

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

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

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

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

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

guest

回答1

0

ベストアンサー

①を関数にしてx1,x2を使うときに呼び出したらよいのではないですか?
理解が間違っていたらすみません。

python

1from scipy.optimize import curve_fit 2import matplotlib.pyplot as plt 3import matplotlib.cm as cm 4import pandas as pd 5import numpy as np 6from scipy import signal 7import os 8from scipy.signal import find_peaks 9 10 11x, y = np.loadtxt("./2_BLT_powder_2th-ome.txt", skiprows=29, unpack=True) 12 13 14def detect_peak(): 15 global x 16 global y 17 peaks, _ = find_peaks(x, height=200) 18 #signal.find_peaks(x, height=高さ, distance=距離) 19 20 # 極大値 orderを変えることでピークの検出が変わる(ピーク検出の閾値) 21 maxid = signal.argrelmax(y, order=100) 22 # minid = signal.argrelmin(y, order=1) #極小値 23 24 x_max = max(x) 25 y_max = max(y) 26 y_min = min(y) 27 x_min = min(x) 28 fig = plt.figure(figsize=(15, 5)) # 図のアスペクト比を変更(横×縦) 29 Map1 = fig.add_subplot(111) 30 Map1.plot(x, y) 31 32 #plt.plot((x, y), pltsize=(6,6)) 33 plt.tick_params(labelsize=9) # 目盛りの数字の大きさを変更 34 plt.ylim(y_min, y_max*1.1) # y 軸の範囲の設定, 35 plt.xlim(10, 65) # x 軸の範囲の設定 36 # plt.show() 37 38 plt.plot(x[maxid], y[maxid], 'ro', label='peak_max') 39 # plt.plot(x[minid],y[minid],'bo',label='ピーク値(最小)') 40 41 plt.legend() 42 return x[maxid], y[maxid] 43 44def func(x, *params): 45 46 #paramsの長さでフィッティングする関数の数を判別。 47 num_func = int(len(params)/3) 48 49 #ガウス関数にそれぞれのパラメータを挿入してy_listに追加。 50 y_list = [] 51 for i in range(num_func): 52 y = np.zeros_like(x) 53 param_range = list(range(3*i,3*(i+1),1)) 54 amp = params[int(param_range[0])] 55 ctr = params[int(param_range[1])] 56 wid = params[int(param_range[2])] 57 y = y + amp * np.exp( -((x - ctr)/wid)**2) 58 y_list.append(y) 59 60 #y_listに入っているすべてのガウス関数を重ね合わせる。 61 y_sum = np.zeros_like(x) 62 for i in y_list: 63 y_sum = y_sum + i 64 65 #最後にバックグラウンドを追加。 66 y_sum = y_sum + params[-1] 67 68 return y_sum 69 70#プロットの定義 71def fit_plot(x, *params): 72 num_func = int(len(params)/3) 73 y_list = [] 74 for i in range(num_func): 75 y = np.zeros_like(x) 76 param_range = list(range(3*i,3*(i+1),1)) 77 amp = params[int(param_range[0])] 78 ctr = params[int(param_range[1])] 79 wid = params[int(param_range[2])] 80 y = y + amp * np.exp( -((x - ctr)/wid)**2) + params[-1] 81 y_list.append(y) 82 return y_list 83 84#初期値のリストを作成 85#[amp,ctr,wid] 86 87# x1, y1 = detect_peak() ## 88np_x, np_y = detect_peak() ## 89 90x2=float(input("x2")) 91y2=float(input("y2")) 92# guess = [] ## 93guess = [[y1, x1, 1] for (x1, y1) in zip(np_x, np_y)] ## 94# guess.append([y1, x1, 1]) ## 95guess.append([y2, x2, 1]) 96 97#バックグラウンドの初期値 98background = 70 99 100#初期値リストの結合 101guess_total = [] 102for i in guess: 103 guess_total.extend(i) 104guess_total.append(background) 105 106popt, pcov = curve_fit(func, x, y, p0=guess_total) 107 108 109 110fit= func(x, *popt) 111plt.scatter(x, y, s=20) 112plt.plot(x, fit , ls='-', c='black', lw=1) 113 114y_list = fit_plot(x, *popt) 115baseline = np.zeros_like(x) + popt[-1] 116for n,i in enumerate(y_list): 117 plt.fill_between(x, i, baseline, facecolor=cm.rainbow(n/len(y_list)), alpha=0.6) 118 119print(*popt)

編集(12/01 17:35) ##が変更点です

投稿2021/12/01 05:07

編集2021/12/01 08:36
irognodyci

総合スコア227

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

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

Nari9113

2021/12/01 05:59

コメントありがとうございます!①のプロット系はいらないので省略して当てはめてみましたがoperands could not be broadcast together with shapes (5328,) (23,) と出てエラーが出ました。 x[maxid]とy[maxid]が複数だからのエラーですかね、、、
irognodyci

2021/12/01 08:35

完全に見落としていました、すみません。 配列扱いで修正しました。
Nari9113

2021/12/01 09:08

ありがとうございます!入力してみましたところOptimal parameters not found: Number of calls to function has reached maxfev = 14200エラーが出てしまいました泣 回答して下さった部分を変更して現在のコードを質問内容の追記部分に載せさせていただきました!
irognodyci

2021/12/01 10:39

どこでエラーが出ているかわかりますか?エラーメッセージと何行目かってでてくると思うのでそのまま貼り付けて質問を更新してもらえるといいかもしれません。
Nari9113

2021/12/01 17:36

返信遅くなり申し訳ありません泣 エラーコード部分を質問に追加させていただきました
irognodyci

2021/12/02 01:45

①でx[maxid]とy[maxid]を出力していたと思うのですが、出力されたものをそのまま全部②のほうに手動で入力したら動くんですかね?例えば、x[maxid] == [10,20,30],y[maxid] == [400,500,600]だったら、②の方で guess.append([400,10,1]) guess.append([500,20,1]) guess.append([600,30,1]) としたら動くのかな?と。全部手動入力したら動くのであればパラメータの問題ではなく手動入力と自動入力の時とのずれになるでしょうし、それでも動かないのであればパラメータに少し手を加えないといけなくなりますし。どこに問題があるかを一つずつ整理していきたいです。
Nari9113

2021/12/02 04:43

元々のコードでは仰っている②のguess.append([])を増やし手動入力は可能でした
irognodyci

2021/12/02 05:21

となると、うまく入ってないんですかね。 手動入力後にprint(guess)した場合と、自動入力の方で入力した後print(guess)した場合とで違いはありますか?
Nari9113

2021/12/02 05:37

自動入力で [[131.0, 10.755, 1], [63.0, 12.205, 1], [58.0, 13.395, 1], [262.0, 16.195, 1], [59.0, 18.395, 1], [194.0, 21.665, 1], [272.0, 23.355, 1], [72.0, 24.635, 1], [113.0, 26.925, 1], [1286.0, 30.055, 1], [440.0, 33.085, 1], [43.0, 34.725, 1], [88.0, 37.025, 1], [251.0, 38.365, 1], [240.0, 39.775, 1], [77.0, 42.855, 1], [287.0, 47.445, 1], [256.0, 51.445, 1], [86.0, 53.505, 1], [39.0, 55.445, 1], [329.0, 57.245, 1], [71.0, 58.555, 1], [134.0, 62.535, 1]] と出たので違いはなさそうです
irognodyci

2021/12/02 06:25 編集

元ファイルがないのでこちらで検証のしようがないのが痛いところです。原因がすぐわからずいろいろさせてしまってすみません、、 手動入力してprintしたものをコピーして、自動入力の方のプログラムで、guess = [[y1, x1, 1] for (x1, y1) in zip(np_x, np_y)]をguess = printしたもの(コピーしたものを貼り付ける) にしても動作しますか?
Nari9113

2021/12/02 06:41

実験結果のファイルなので渡したいぐらいです、、いえいえ!進んでる気がしてむしろ喜んでいます笑 ちゃんと理解して入力できているか分かりませんがguess = [[1286, 30.055, 1],[440, 33, 1]] のように入れ込めば表示されました
Nari9113

2021/12/02 06:46

計算が多すぎる問題ですかね、、(´;ω;`)
Nari9113

2021/12/02 06:53

このデータ、全部入れてみようとしたらできず、後ろ4組分消したところ反映されました ピークのノイズ分も計算して後から消そうとしていたので計算量が多くなったのかと泣 最初ノイズ部分を消せなかったのでノイズ部分を消せたら全部動くかもしれません泣
irognodyci

2021/12/02 07:26 編集

手動入力してたときは少ないデータでやっていたってことですか? ノイズまで拾っていると思うと全部手動入力は厳しそうですが(-_-;)
Nari9113

2021/12/02 07:34

まずプログラムが動くかを試していたので少ないデータで行っていました、、 ある程度のノイズ除去まではしていたので、、まだ多かったみたいです泣
Nari9113

2021/12/02 07:39

guessの入れ込む前にノイズと思われるyがバックグラウンドの二倍ほどであればその組を省くということは可能ですか?
irognodyci

2021/12/02 08:04

background = 70 guess = [[y1, x1, 1] for (x1, y1) in zip(np_x, np_y) if background * 2 > y1] でできると思います。backgroundを先に定義したのと、リスト内包表記の後ろの方にif文付けただけです!
irognodyci

2021/12/02 08:06

そもそもノイズをピークとして拾ってる場合ってピークフィッティングできるんでしょうか?
Nari9113

2021/12/02 08:16

ありがとうございます! ノイズを除いたデータ(元のデータとは別)で行っていたので可能でした 最初からまとめて行うと訳が分からなくなりそうだったので、、
Nari9113

2021/12/02 08:20

バックグラウンド2倍以下除去の関数を打ち込んだところエラーコードの最後がmaxfev = 6400に変わりました
irognodyci

2021/12/02 08:31

popt, pcov = curve_fit(func, x, y, p0=guess_total, maxfev=14200) maxfevを変えると推測回数が変わるので、すごく大きくしたらいける、、のか? この辺は触ったことないので僕もわかってなくて
Nari9113

2021/12/02 08:55

50000も駄目で100000にしたらいけました!!!!!!(いや関数呼び出し多すぎ、、) 後は出た値をリスト化するだけになりました!本当にありがとうございます!!!
irognodyci

2021/12/02 09:29

それでいいのか感は少しありますが、とりあえず動いて良かったです!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問