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

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

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

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

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

Q&A

0回答

1151閲覧

pythonでのガウシアンフィットでエラー(誤差)も出力したい

mappys

総合スコア104

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

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

0グッド

0クリップ

投稿2022/02/07 17:11

pythonでのガウシアンフィットでエラー(誤差)も出力したいです。
詳しい方お力をお借りしたいです。
コード、結果のグラフは以下です。
イメージ説明

python

1#モジュールのインポート 2#import モジュール名 as * は非推奨。使っているコードを見かけますけど。 3import pandas as pd 4import numpy as np 5from scipy.optimize import curve_fit 6import matplotlib.pyplot as plt 7import matplotlib.gridspec as gridspec 8 9#データの読み込み 10#関連として df を用いるが、データに即した変数名を使うべき。 11#ベクトルとして取り出すことも可能。 12#ただし、x, y を個別に取り出した方がフィッティングの際に扱いやすい。 13#engine='python' と指定すると日本語ファイルも読み込めます。 14#file = '元データ.csv' 15#df = pd.read_csv(file, engine='python', skiprows=None, nrows=None, header=None) 16 17input_csv = pd.read_csv('元データ.csv') 18channels = input_csv[input_csv.keys()[0]] 19counts = input_csv[input_csv.keys()[1]] 20 21#元データがint値で、そのままではフィッティングできないので、float型に変換している。 22#channels = np.array(df.iloc[:, 0], dtype=float) 23#counts = np.array(df.iloc[:, 1], dtype=float) 24 25#フィッティング関数の定義 26#n次式を定義しやすいように、0次から記述した。 27def quadratic(x, a, b, c): 28 return a + b * x + c * x**2 29 30 31#ガウシアンはより簡素に記述できるが、初期値を類推しやすい式にした。 32def gauss(x, a, sigma, mean): 33 #return a / np.sqrt(2.0*np.pi) / sigma * np.exp(-((x-mean)/sigma)**2/2) 34 return a * np.exp(-((x-mean)/sigma)**2/2) 35#フィッティング関数は二次関数とガウシアンをまとめて定義してもよい。 36#ガウシアンを三度呼び出すので、分けて記述した。 37#文頭のアスタリスクのついた*paramaters は引数を幾らでも渡せる。 38#本来ならば引数を個別に指定すべき。 39#今回はあまりにも冗長になるため、*paramaters と指定した。 40def fitting(x, *paramaters): 41 a0, b0, c0, a1, sigma1, mean1, a2, sigma2, mean2, a3, sigma3, mean3, = paramaters 42 return quadratic(x, a0, b0, c0) + \ 43 gauss(x, a1, sigma1, mean1) + \ 44 gauss(x, a2, sigma2, mean2) + \ 45 gauss(x, a3, sigma3, mean3) 46 47#初期値の設定。 48#ガウシアンの場合、meanを適切に設定しないと発散しやすい。 49#線形近似であっても適切に設定することが望ましい。 50#関数の引数が複数ある場合は、タプルで渡すこと。 51#initial_quadratic = 80000, -0.07,0 #a0, b0, c0 52initial_quadratic = 0, 0,0 #a0, b0, c0 53#initial_gauss1 = 889000, 3000, 236000 #a1, sigma1, mean1 54#initial_gauss2 = 824000, 3000,1000000 #a2, sigma2, mean2 55#initial_gauss3 = 741000, 3000,1761000 #a3, sigma3, mean3 56#110000000000 57initial_gauss1 = 889000, 52993, 236000 #a1, sigma1, mean1 58initial_gauss2 = 889000, 59083, 999000 #a2, sigma2, mean2 59initial_gauss3 = 889000, 67539,1761000 #a3, sigma3, mean3 60 61#初期値が多いので、個別に指定して接続した。 62initial_parameter = initial_quadratic + initial_gauss1 + initial_gauss2 + initial_gauss3 63 64#フィッティングの実行 65#paramater_optimalが最適化されたパラメータで、covarianceは共分散。 66paramater_optimal, covariance = curve_fit(fitting, channels, counts, initial_parameter) 67#paramater_optimal = initial_parameter 68#matplotlibの設定 69plt.rc('font', family='Arial', size=14) #フォントの設定 70plt.rc('xtick.major', width=1, size=6) #x軸の主目盛りの設定 71plt.rc('xtick', direction='in', top=True) #x軸目盛りの向き、上側に表示するか 72plt.rc('ytick.major', width=1, size=6) #y軸の主目盛りの設定 73plt.rc('ytick', direction='in', right=True) #y軸目盛りの向き、右側に表示するか 74plt.rc('axes', linewidth=1.5) #枠線の太さ 75plt.rc('lines', linewidth=1.0) #プロットの太さ 76 77#今回は、Axes が一つしかないので fig, ax1 = plt.subplots() の方が簡素。 78#慣例として ax1 を用いるが、df 同様に意味のある変数名にすべき。 79fig = plt.figure(figsize=(8, 6), dpi=80) 80gs = gridspec.GridSpec(1, 1) 81ax1 = fig.add_subplot(gs[0]) 82 83#データをグラフに表示する。 84ax1.plot(channels, counts, ls='-', c='g', label='row data') 85ax1.set_xlabel('Channel', fontsize=16) 86ax1.set_ylabel('Count', fontsize=16) 87ax1.yaxis.set_data_interval(0,10) #set_ylim を使う方が一般的 88 89#フィッティングした曲線の表示 90#np.corrcoef で相関係数を求める。 91#結果が2×2の行列で返るので、1行目2列目もしくは2行目1列目の値を取得。 92ax1.plot(channels, fitting(channels, *paramater_optimal), 93 lw=1.5, ls='--', c='k', label='fitting curve\n' + \ 94 f'$R^2$ = {np.corrcoef(counts, fitting(channels, *paramater_optimal))[0][1]}') 95 96#二次関数のパラメーターを利用したいので、スライスで取り出す。 97a0, b0, c0 = paramater_optimal[0:3] 98 99ax1.plot(channels, quadratic(channels, a0, b0, c0), c='b', 100 label=r'$y = a_0 + b_0x + c_0x^2$' +'\n'+ f'$a_0$ = {a0}\nb$_0$ = {b0}\nc$_0$ = {c0}') 101 102#各meanをグラフ上に表示する。繰り返しのため for 文を利用。 103for i in range(3,12,3): 104#この関数内の、a0, b0, c0 はグローバル変数である。 105 def quadratic_gauss(x, *paramaters): 106 a1, sigma1, mean1, = paramaters 107 return quadratic(x, a0, b0, c0) + \ 108 gauss(x, a1, sigma1, mean1) 109 110#annotate で Axes 内にテキストや矢印を表示できる。 111 mean = paramater_optimal[i+2] 112 sigma = paramater_optimal[i+1] 113 ax1.annotate(int(mean), fontsize = 14, 114 xy=(mean, quadratic_gauss(mean, *paramater_optimal[i:i+3])+3), 115 xytext=(mean, quadratic_gauss(mean, *paramater_optimal[i:i+3])+15), 116 ha="center", va='top', 117 arrowprops=dict(shrink=0.05, facecolor='k')) 118 print(mean,sigma) 119 120#凡例の表示。Figure の判例を出力することもできる。 121ax1.legend(loc='upper right', frameon=False) 122 123gs.tight_layout(fig) #グラフ描画前に行うべし。慣例では、fig.tight_layout() 124plt.show() #慣例では plt.show() と fig を指定しない。 125

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問