Python 実験データを自作関数にフィッティングする「scipy.optimize」

本プログラム実行後のグラフを下図に示す。青点は実験データ(便宜上、手で作成)、赤線はガウス関数でのフィッティング後をプロットしている。

f:id:HK29:20180506212756p:plain

▼本プログラム

フィッテイングはScipyのoptimizeを利用しており、最適値は初期値の設定に依存する。他には、matplotlibによるグラフ表示設定についても多数記載している。

# -*- coding: utf-8 -*- 
#!/usr/bin/env python

import numpy as np
import matplotlib
matplotlib.use('Agg') # グラフをウィンドウ表示しない。GUI表示できないサーバモニタ等で重宝する[1]
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import csv

##### 生データ
xdata = np.linspace(5, 11, 30)
ydata = np.array([1.9e16, 2.2e16, 2.5e16, 2.1e16, 2.8e16, 2.9e16, 2.2e16, 2.6e16, 2.4e16, 3.6e16,
                  5.5e16, 9.2e16, 2.5e17, 1.1e18, 3.4e18, 5.5e18, 2.2e18, 5.1e17, 1.3e17, 5.4e16, 
                  8.9e16, 5.7e16, 2.5e16, 5.1e16, 5.6e16, 3.2e16, 3.0e16, 2.5e16, 2.1e16, 1.8e16])

##### フィッティングする関数y=f(x)の定義
def func(x, a, mu, sigma, c):
    return a*np.exp(-(x-mu)**2/(2*sigma**2)) + c

##### 最適化するy=f(x)の係数の初期値
prameter_initial = np.array([1e18, 8, 3, 1e15])

##### 最適化の計算[2]
popt, pcov = curve_fit(func, xdata, ydata, p0= prameter_initial)
print ("parameter ->", popt)

##### 最適化後のy=f(x)の関数
#y = func(xdata, popt[0], popt[1], popt[2], popt[3])
y = func(xdata, *popt)

##### 生データと最適化後の関数をグラフにプロット
# 元の生データを点プロット
plt.scatter(xdata, ydata, c='blue', label='raw data')
# 最適化後のフィット関数を線でプロット
plt.plot(xdata, y, 'r-',
         label = 'fit: a=%2.2E, mu=%3.2f, sigma=%3.2f, c=%2.2E' \
         % tuple(popt))

##### グラフ表示のオプション設定 #####
plt.xlabel('x', fontsize=18)     # x軸の名称とフォントサイズ
plt.ylabel('y', fontsize=18)     # y軸の名称とフォントサイズ
plt.yscale("log")                # y軸のスケールをログに指定
plt.ylim([1e15,1e20])            # y軸のレンジの範囲を指定
plt.grid(which="both")           # 表中にグリッド入れる
#plt.rcParams["font.size"]=16    # 全体のフォントを変更
plt.legend(loc='upper right')    # ラベルを右上に記載
plt.tight_layout()               # タイトルを重ねない
plt.show()                       # グラフをプロット
plt.savefig("optimize_fit.png")  # 画像をファイルで保存

参考ページ

[1] scipyのoptimizeのcurve_fit
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html#scipy.optimize.curve_fit
[2] matplotlibでウィンドウ表示せずにイメージを保存する方法
https://matplotlib.org/faq/howto_faq.html#generate-images-without-having-a-window-appear

以上

<広告>