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

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

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

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

NumPy

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

Python

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

Q&A

解決済

1回答

1180閲覧

Pythonでのガウシアンフィッティングでエラーが出る

mappys

総合スコア104

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

NumPy

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

Python

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

1グッド

0クリップ

投稿2022/02/03 09:54

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)
このエラーが原因だと思うのですが、どうしたらいいかわからないです。詳しい方お力をお借りしたいです。

melian👍を押しています

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

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

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

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

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

melian

2022/02/03 12:03

shape が (1500,3) なので、画像を BGR モードで読み込んでいるのだと思います。なので、グレースケールで読み込むとよいのではないでしょうか。 img = cv2.imread('img.png', 0) それと、quadratic 関数のパラメータ x にリストが渡される場合があるので、そこでエラーが発生します。
mappys

2022/02/03 12:24

melian様 回答ありがとうございます! img = cv2.imread('img.png', 0) で読み込んでみたところ、エラー内容が変わりました。質問させていただいたエラーはクリアできたのかなと思います。ありがとうございます! 次に出たエラーが以下になります。 /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/scipy/optimize/minpack.py:833: OptimizeWarning: Covariance of the parameters could not be estimated warnings.warn('Covariance of the parameters could not be estimated', Traceback (most recent call last): File "/Users/masashi/pyworks/gaus.py", line 81, in <module> ax1.plot(channels, fitting(channels, *paramater_optimal), File "/Users/masashi/pyworks/gaus.py", line 36, in fitting return quadratic(x, a0, b0, c0) + \ File "/Users/pyworks/gaus.py", line 23, in quadratic return a + b * x + c * x**2 TypeError: can't multiply sequence by non-int of type 'numpy.float64' このようなまた別のエラーが出てしまいました。。。 >>それと、quadratic 関数のパラメータ x にリストが渡される場合があるので、そこでエラーが発生します。 ここに関していまいち理解できていないのですが、ご指摘いただいたこの点がエラーになってしまっている感じでしょうか?
melian

2022/02/03 12:31

はい、そうです。quadratic 関数の中身をみますと、x は numpy の array でないとエラーになってしまいます。なので、 def quadratic(x, a, b, c): x = np.array(x) return a + b * x + c * x**2 としてみるとよいかと思います。これでフィッティングの結果はでますが。。。
mappys

2022/02/03 12:42

エラー文を見なくてもエラーが出るところがわかるのがすごすぎて感動しております。 ご指摘いただいた部分を書き加えたところ無事結果が出力されました。 ただまともにフィッティングできていない様子です笑 初期値などのパラメータが適切ではないためでしょうか。。。 結果は出力されますが以下の文が出てきます /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/scipy/optimize/minpack.py:833: OptimizeWarning: Covariance of the parameters could not be estimated warnings.warn('Covariance of the parameters could not be estimated', おそらくパラメータが適切ではないよ、って意味ですよね。 コードの初期値の部分↓ initial_quadratic = 0.1, 0.1, 0.1 #a0, b0, c0 initial_gauss1 = 2500, 464, 170. #a1, sigma1, mean1 initial_gauss2 = 2400, 1000, 100. #a2, sigma2, mean2 initial_gauss3 = 2000, 1300, 100. #a3, sigma3, mean3 ここを見直す必要がありそうですね。 ひとまず出力まではいけました!本当にありがとうございます。
mappys

2022/02/03 12:49

出力された結果を見ると、quadratic 関数は特に必要なく、ガウス関数のみでフィッテイングした方が良さそうな気がしてきましたので、quadratic 関数を消す方向でもやってみようと思います。
mappys

2022/02/03 12:59

試行錯誤した結果、無事フィッティングできました! 本当にありがとうございました。
guest

回答1

0

自己解決

melian様のアドバイスで解決できました。
・画像の読み込みをグレースケールで行うこと
・def quadratic(x, a, b, c):
x = np.array(x)
return a + b * x + c * x**2

と書き足すことで解決しました。

投稿2022/02/03 13:01

mappys

総合スコア104

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問