Pythonでガウシアンフィッティングしようとすると以下のようなエラーが出てしまいます。
File "/Users/pyworks/gaus.py", line 54, in <module> paramater_optimal, covariance = curve_fit(fitting, channels, counts, initial_parameter) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/scipy/optimize/minpack.py", line 789, in curve_fit res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/scipy/optimize/minpack.py", line 410, in leastsq shape, dtype = _check_func('leastsq', 'func', func, x0, args, n) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/scipy/optimize/minpack.py", line 24, in _check_func res = atleast_1d(thefunc(*((x0[:numinputs],) + args))) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/scipy/optimize/minpack.py", line 485, in func_wrapped return func(xdata, *params) - ydata ValueError: operands could not be broadcast together with shapes (1500,) (1500,3)
実行したコードは以下です。
https://lastline.hatenablog.com/entry/2018/04/12/112502
を参考にしています。このサイトに載ってるコードのフィッティングする元データと初期値のみいじっております。
Python
1#モジュールのインポート 2import pandas as pd 3import numpy as np 4from scipy.optimize import curve_fit 5import matplotlib.pyplot as plt 6import matplotlib.gridspec as gridspec 7import cv2 8 9#フィッティングしたいデータの生成 10img = cv2.imread('convert.png') #1500×360の画像読み込み 11img_split = np.split(img, 36) 12#元々の配列(1500×360)の時、縦を36分割、1500×10の配列を36個生成 13 14#フィッティングしたいデータ 15channels=list(range(1500)) 16counts=np.sum(img_split[0],axis=0) 17 18 19#フィッティング関数の定義 20def quadratic(x, a, b, c): 21 return a + b * x + c * x**2 22 23#ガウシアンはより簡素に記述できるが、初期値を類推しやすい式にした。 24def gauss(x, a, sigma, mean): 25 return a / np.sqrt(2.0*np.pi) / sigma * np.exp(-((x-mean)/sigma)**2/2) 26 27#今回はあまりにも冗長になるため、*paramaters と指定した。 28def fitting(x, *paramaters): 29 a0, b0, c0, a1, sigma1, mean1, a2, sigma2, mean2, a3, sigma3, mean3, = paramaters 30 return quadratic(x, a0, b0, c0) + \ 31 gauss(x, a1, sigma1, mean1) + \ 32 gauss(x, a2, sigma2, mean2) + \ 33 gauss(x, a3, sigma3, mean3) 34 35#初期値の設定。 36#ガウシアンの場合、meanを適切に設定しないと発散しやすい。 37#線形近似であっても適切に設定することが望ましい。 38#関数の引数が複数ある場合は、タプルで渡すこと。 39initial_quadratic = 0.1, 0.1, 0.1 #a0, b0, c0 40initial_gauss1 = 2500, 464, 170. #a1, sigma1, mean1 41initial_gauss2 = 2400, 1000, 100. #a2, sigma2, mean2 42initial_gauss3 = 2000, 1300, 100. #a3, sigma3, mean3 43 44#初期値が多いので、個別に指定して接続した。 45initial_parameter = initial_quadratic + initial_gauss1 + initial_gauss2 + initial_gauss3 46 47#フィッティングの実行 48#paramater_optimalが最適化されたパラメータで、covarianceは共分散。 49paramater_optimal, covariance = curve_fit(fitting, channels, counts, initial_parameter) 50 51#matplotlibの設定 52plt.rc('font', family='Arial', size=14) #フォントの設定 53plt.rc('xtick.major', width=1, size=6) #x軸の主目盛りの設定 54plt.rc('xtick', direction='in', top=True) #x軸目盛りの向き、上側に表示するか 55plt.rc('ytick.major', width=1, size=6) #y軸の主目盛りの設定 56plt.rc('ytick', direction='in', right=True) #y軸目盛りの向き、右側に表示するか 57plt.rc('axes', linewidth=1.5) #枠線の太さ 58plt.rc('lines', linewidth=1.0) #プロットの太さ 59 60#今回は、Axes が一つしかないので fig, ax1 = plt.subplots() の方が簡素。 61#慣例として ax1 を用いるが、df 同様に意味のある変数名にすべき。 62fig = plt.figure(figsize=(8, 6), dpi=80) 63gs = gridspec.GridSpec(1, 1) 64ax1 = fig.add_subplot(gs[0]) 65 66#データをグラフに表示する。 67ax1.plot(channels, counts, ls='-', c='g', label='row data') 68ax1.set_xlabel('Channel', fontsize=16) 69ax1.set_ylabel('Count', fontsize=16) 70ax1.yaxis.set_data_interval(0, 100) #set_ylim を使う方が一般的 71 72#フィッティングした曲線の表示 73#np.corrcoef で相関係数を求める。 74#結果が2×2の行列で返るので、1行目2列目もしくは2行目1列目の値を取得。 75ax1.plot(channels, fitting(channels, *paramater_optimal), 76 lw=1.5, ls='--', c='k', label='fitting curve\n' + \ 77 f'$R^2$ = {np.corrcoef(counts, fitting(channels, *paramater_optimal))[0][1]}') 78 79#二次関数のパラメーターを利用したいので、スライスで取り出す。 80a0, b0, c0 = paramater_optimal[0:3] 81 82ax1.plot(channels, quadratic(channels, a0, b0, c0), c='b', 83 label=r'$y = a_0 + b_0x + c_0x^2$' +'\n'+ f'$a_0$ = {a0}\nb$_0$ = {b0}\nc$_0$ = {c0}') 84 85#各meanをグラフ上に表示する。繰り返しのため for 文を利用。 86for i in range(3,12,3): 87#この関数内の、a0, b0, c0 はグローバル変数である。 88 def quadratic_gauss(x, *paramaters): 89 a1, sigma1, mean1, = paramaters 90 return quadratic(x, a0, b0, c0) + \ 91 gauss(x, a1, sigma1, mean1) 92 93#annotate で Axes 内にテキストや矢印を表示できる。 94 mean = paramater_optimal[i+2] 95 ax1.annotate(int(mean), fontsize = 14, 96 xy=(mean, quadratic_gauss(mean, *paramater_optimal[i:i+3])+3), 97 xytext=(mean, quadratic_gauss(mean, *paramater_optimal[i:i+3])+15), 98 ha="center", va='top', 99 arrowprops=dict(shrink=0.05, facecolor='k')) 100 101#凡例の表示。Figure の判例を出力することもできる。 102ax1.legend(loc='upper right', frameon=False) 103 104gs.tight_layout(fig) #グラフ描画前に行うべし。慣例では、fig.tight_layout() 105plt.show(fig) #慣例では plt.show() と fig を指定しない。 106
ValueError: operands could not be broadcast together with shapes (1500,) (1500,3)
このエラーが原因だと思うのですが、どうしたらいいかわからないです。詳しい方お力をお借りしたいです。

回答1件
あなたの回答
tips
プレビュー