Scipy curve_fit for Two Dimensions Not Working - Object Too Deep?












1















I have a 2400 by 2400 array of data which looks something like this:



data = [[-2.302670298082603040e-01 -2.304885241061924717e-01 -2.305029774024092148e-01 -2.304807100897505734e-01 -2.303702531336284665e-01 -2.307144352067780346e-01...
[-2.302670298082603040e-01 -2.304885241061924717e-01 -2.305029774024092148e-01 -2.304807100897505734e-01 -2.303702531336284665e-01 -2.307144352067780346e-01...
...


and I am trying to fit the following 2D Gaussian function:



def Gauss2D(x, mux, muy, sigmax, sigmay, amplitude, offset, rotation):
assert len(x) == 2
X = x[0]
Y = x[1]
A = (np.cos(rotation)**2)/(2*sigmax**2) + (np.sin(rotation)**2)/(2*sigmay**2)
B = (np.sin(rotation*2))/(4*sigmay**2) - (np.sin(2*rotation))/(4*sigmax**2)
C = (np.sin(rotation)**2)/(2*sigmax**2) + (np.cos(rotation)**2)/(2*sigmay**2)
G = amplitude*np.exp(-((A * (X - mux) ** 2) + (2 * B * (X - mux) * (Y - muy)) + (C * (Y - muy) ** 2))) + offset
return G


to this data, using scipy curve_fit. I have therefore defined the domain of the independent variables (coordinates) as follows:



vert = np.arange(2400, dtype=float)
horiz = np.arange(2400, dtype=float)
HORIZ, VERT = np.meshgrid(horiz, vert)


and as an initial estimate of the parameters:



po = np.asarray([1200., 1200., 300., 300., 0.14, 0.22, 0.], dtype=float)


so that I can perform the following fit:



popt, pcov = curve_fit(Gauss2D, (HORIZ, VERT), data, p0=po)


This is returning the following error message, and I haven't the faintest clue why:



---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
ValueError: object too deep for desired array
---------------------------------------------------------------------------
error Traceback (most recent call last)
<ipython-input-11-ebba75332bfa> in <module>()
----> 1 curve_fit(Gauss2D, (HORIZ, VERT), data, p0=po)

/home/harrythegenius/anaconda3/lib/python3.6/site-packages/scipy/optimize/minpack.py in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs)
734 # Remove full_output from kwargs, otherwise we're passing it in twice.
735 return_full = kwargs.pop('full_output', False)
--> 736 res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
737 popt, pcov, infodict, errmsg, ier = res
738 cost = np.sum(infodict['fvec'] ** 2)

/home/harrythegenius/anaconda3/lib/python3.6/site-packages/scipy/optimize/minpack.py in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
385 maxfev = 200*(n + 1)
386 retval = _minpack._lmdif(func, x0, args, full_output, ftol, xtol,
--> 387 gtol, maxfev, epsfcn, factor, diag)
388 else:
389 if col_deriv:

error: Result from function call is not a proper array of floats.


I don't understand the message "object too deep for desired array". I have also seen multiple online solutions to this error message, in which one would fix it by ensuring that all data types which were passed to curve_fit were floats, or by checking that the dimensions of the arrays were correct. I have tried both of these approaches, time and time again, but it makes no difference. So what's wrong with this one?










share|improve this question























  • Just to be clear, what is data.shape and data.dtype? You need to show some of that data checking.

    – hpaulj
    Nov 13 '18 at 16:31













  • Shape is (2400, 2400).

    – Harry Chittenden
    Nov 13 '18 at 16:39











  • dtype is float64

    – Harry Chittenden
    Nov 13 '18 at 16:39











  • HORIZ is a 2d array, (2400,2400). Have you tried calling this with (horiz, vert) instead?

    – hpaulj
    Nov 13 '18 at 16:49






  • 1





    If you give us a Minimal, Complete, and Verifiable example, something we can copy-n-paste and run, we might be able to help more.

    – hpaulj
    Nov 13 '18 at 17:10
















1















I have a 2400 by 2400 array of data which looks something like this:



data = [[-2.302670298082603040e-01 -2.304885241061924717e-01 -2.305029774024092148e-01 -2.304807100897505734e-01 -2.303702531336284665e-01 -2.307144352067780346e-01...
[-2.302670298082603040e-01 -2.304885241061924717e-01 -2.305029774024092148e-01 -2.304807100897505734e-01 -2.303702531336284665e-01 -2.307144352067780346e-01...
...


and I am trying to fit the following 2D Gaussian function:



def Gauss2D(x, mux, muy, sigmax, sigmay, amplitude, offset, rotation):
assert len(x) == 2
X = x[0]
Y = x[1]
A = (np.cos(rotation)**2)/(2*sigmax**2) + (np.sin(rotation)**2)/(2*sigmay**2)
B = (np.sin(rotation*2))/(4*sigmay**2) - (np.sin(2*rotation))/(4*sigmax**2)
C = (np.sin(rotation)**2)/(2*sigmax**2) + (np.cos(rotation)**2)/(2*sigmay**2)
G = amplitude*np.exp(-((A * (X - mux) ** 2) + (2 * B * (X - mux) * (Y - muy)) + (C * (Y - muy) ** 2))) + offset
return G


to this data, using scipy curve_fit. I have therefore defined the domain of the independent variables (coordinates) as follows:



vert = np.arange(2400, dtype=float)
horiz = np.arange(2400, dtype=float)
HORIZ, VERT = np.meshgrid(horiz, vert)


and as an initial estimate of the parameters:



po = np.asarray([1200., 1200., 300., 300., 0.14, 0.22, 0.], dtype=float)


so that I can perform the following fit:



popt, pcov = curve_fit(Gauss2D, (HORIZ, VERT), data, p0=po)


This is returning the following error message, and I haven't the faintest clue why:



---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
ValueError: object too deep for desired array
---------------------------------------------------------------------------
error Traceback (most recent call last)
<ipython-input-11-ebba75332bfa> in <module>()
----> 1 curve_fit(Gauss2D, (HORIZ, VERT), data, p0=po)

/home/harrythegenius/anaconda3/lib/python3.6/site-packages/scipy/optimize/minpack.py in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs)
734 # Remove full_output from kwargs, otherwise we're passing it in twice.
735 return_full = kwargs.pop('full_output', False)
--> 736 res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
737 popt, pcov, infodict, errmsg, ier = res
738 cost = np.sum(infodict['fvec'] ** 2)

/home/harrythegenius/anaconda3/lib/python3.6/site-packages/scipy/optimize/minpack.py in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
385 maxfev = 200*(n + 1)
386 retval = _minpack._lmdif(func, x0, args, full_output, ftol, xtol,
--> 387 gtol, maxfev, epsfcn, factor, diag)
388 else:
389 if col_deriv:

error: Result from function call is not a proper array of floats.


I don't understand the message "object too deep for desired array". I have also seen multiple online solutions to this error message, in which one would fix it by ensuring that all data types which were passed to curve_fit were floats, or by checking that the dimensions of the arrays were correct. I have tried both of these approaches, time and time again, but it makes no difference. So what's wrong with this one?










share|improve this question























  • Just to be clear, what is data.shape and data.dtype? You need to show some of that data checking.

    – hpaulj
    Nov 13 '18 at 16:31













  • Shape is (2400, 2400).

    – Harry Chittenden
    Nov 13 '18 at 16:39











  • dtype is float64

    – Harry Chittenden
    Nov 13 '18 at 16:39











  • HORIZ is a 2d array, (2400,2400). Have you tried calling this with (horiz, vert) instead?

    – hpaulj
    Nov 13 '18 at 16:49






  • 1





    If you give us a Minimal, Complete, and Verifiable example, something we can copy-n-paste and run, we might be able to help more.

    – hpaulj
    Nov 13 '18 at 17:10














1












1








1








I have a 2400 by 2400 array of data which looks something like this:



data = [[-2.302670298082603040e-01 -2.304885241061924717e-01 -2.305029774024092148e-01 -2.304807100897505734e-01 -2.303702531336284665e-01 -2.307144352067780346e-01...
[-2.302670298082603040e-01 -2.304885241061924717e-01 -2.305029774024092148e-01 -2.304807100897505734e-01 -2.303702531336284665e-01 -2.307144352067780346e-01...
...


and I am trying to fit the following 2D Gaussian function:



def Gauss2D(x, mux, muy, sigmax, sigmay, amplitude, offset, rotation):
assert len(x) == 2
X = x[0]
Y = x[1]
A = (np.cos(rotation)**2)/(2*sigmax**2) + (np.sin(rotation)**2)/(2*sigmay**2)
B = (np.sin(rotation*2))/(4*sigmay**2) - (np.sin(2*rotation))/(4*sigmax**2)
C = (np.sin(rotation)**2)/(2*sigmax**2) + (np.cos(rotation)**2)/(2*sigmay**2)
G = amplitude*np.exp(-((A * (X - mux) ** 2) + (2 * B * (X - mux) * (Y - muy)) + (C * (Y - muy) ** 2))) + offset
return G


to this data, using scipy curve_fit. I have therefore defined the domain of the independent variables (coordinates) as follows:



vert = np.arange(2400, dtype=float)
horiz = np.arange(2400, dtype=float)
HORIZ, VERT = np.meshgrid(horiz, vert)


and as an initial estimate of the parameters:



po = np.asarray([1200., 1200., 300., 300., 0.14, 0.22, 0.], dtype=float)


so that I can perform the following fit:



popt, pcov = curve_fit(Gauss2D, (HORIZ, VERT), data, p0=po)


This is returning the following error message, and I haven't the faintest clue why:



---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
ValueError: object too deep for desired array
---------------------------------------------------------------------------
error Traceback (most recent call last)
<ipython-input-11-ebba75332bfa> in <module>()
----> 1 curve_fit(Gauss2D, (HORIZ, VERT), data, p0=po)

/home/harrythegenius/anaconda3/lib/python3.6/site-packages/scipy/optimize/minpack.py in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs)
734 # Remove full_output from kwargs, otherwise we're passing it in twice.
735 return_full = kwargs.pop('full_output', False)
--> 736 res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
737 popt, pcov, infodict, errmsg, ier = res
738 cost = np.sum(infodict['fvec'] ** 2)

/home/harrythegenius/anaconda3/lib/python3.6/site-packages/scipy/optimize/minpack.py in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
385 maxfev = 200*(n + 1)
386 retval = _minpack._lmdif(func, x0, args, full_output, ftol, xtol,
--> 387 gtol, maxfev, epsfcn, factor, diag)
388 else:
389 if col_deriv:

error: Result from function call is not a proper array of floats.


I don't understand the message "object too deep for desired array". I have also seen multiple online solutions to this error message, in which one would fix it by ensuring that all data types which were passed to curve_fit were floats, or by checking that the dimensions of the arrays were correct. I have tried both of these approaches, time and time again, but it makes no difference. So what's wrong with this one?










share|improve this question














I have a 2400 by 2400 array of data which looks something like this:



data = [[-2.302670298082603040e-01 -2.304885241061924717e-01 -2.305029774024092148e-01 -2.304807100897505734e-01 -2.303702531336284665e-01 -2.307144352067780346e-01...
[-2.302670298082603040e-01 -2.304885241061924717e-01 -2.305029774024092148e-01 -2.304807100897505734e-01 -2.303702531336284665e-01 -2.307144352067780346e-01...
...


and I am trying to fit the following 2D Gaussian function:



def Gauss2D(x, mux, muy, sigmax, sigmay, amplitude, offset, rotation):
assert len(x) == 2
X = x[0]
Y = x[1]
A = (np.cos(rotation)**2)/(2*sigmax**2) + (np.sin(rotation)**2)/(2*sigmay**2)
B = (np.sin(rotation*2))/(4*sigmay**2) - (np.sin(2*rotation))/(4*sigmax**2)
C = (np.sin(rotation)**2)/(2*sigmax**2) + (np.cos(rotation)**2)/(2*sigmay**2)
G = amplitude*np.exp(-((A * (X - mux) ** 2) + (2 * B * (X - mux) * (Y - muy)) + (C * (Y - muy) ** 2))) + offset
return G


to this data, using scipy curve_fit. I have therefore defined the domain of the independent variables (coordinates) as follows:



vert = np.arange(2400, dtype=float)
horiz = np.arange(2400, dtype=float)
HORIZ, VERT = np.meshgrid(horiz, vert)


and as an initial estimate of the parameters:



po = np.asarray([1200., 1200., 300., 300., 0.14, 0.22, 0.], dtype=float)


so that I can perform the following fit:



popt, pcov = curve_fit(Gauss2D, (HORIZ, VERT), data, p0=po)


This is returning the following error message, and I haven't the faintest clue why:



---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
ValueError: object too deep for desired array
---------------------------------------------------------------------------
error Traceback (most recent call last)
<ipython-input-11-ebba75332bfa> in <module>()
----> 1 curve_fit(Gauss2D, (HORIZ, VERT), data, p0=po)

/home/harrythegenius/anaconda3/lib/python3.6/site-packages/scipy/optimize/minpack.py in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs)
734 # Remove full_output from kwargs, otherwise we're passing it in twice.
735 return_full = kwargs.pop('full_output', False)
--> 736 res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
737 popt, pcov, infodict, errmsg, ier = res
738 cost = np.sum(infodict['fvec'] ** 2)

/home/harrythegenius/anaconda3/lib/python3.6/site-packages/scipy/optimize/minpack.py in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
385 maxfev = 200*(n + 1)
386 retval = _minpack._lmdif(func, x0, args, full_output, ftol, xtol,
--> 387 gtol, maxfev, epsfcn, factor, diag)
388 else:
389 if col_deriv:

error: Result from function call is not a proper array of floats.


I don't understand the message "object too deep for desired array". I have also seen multiple online solutions to this error message, in which one would fix it by ensuring that all data types which were passed to curve_fit were floats, or by checking that the dimensions of the arrays were correct. I have tried both of these approaches, time and time again, but it makes no difference. So what's wrong with this one?







python optimization scipy curve-fitting gaussian






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 13 '18 at 15:58









Harry ChittendenHarry Chittenden

62




62













  • Just to be clear, what is data.shape and data.dtype? You need to show some of that data checking.

    – hpaulj
    Nov 13 '18 at 16:31













  • Shape is (2400, 2400).

    – Harry Chittenden
    Nov 13 '18 at 16:39











  • dtype is float64

    – Harry Chittenden
    Nov 13 '18 at 16:39











  • HORIZ is a 2d array, (2400,2400). Have you tried calling this with (horiz, vert) instead?

    – hpaulj
    Nov 13 '18 at 16:49






  • 1





    If you give us a Minimal, Complete, and Verifiable example, something we can copy-n-paste and run, we might be able to help more.

    – hpaulj
    Nov 13 '18 at 17:10



















  • Just to be clear, what is data.shape and data.dtype? You need to show some of that data checking.

    – hpaulj
    Nov 13 '18 at 16:31













  • Shape is (2400, 2400).

    – Harry Chittenden
    Nov 13 '18 at 16:39











  • dtype is float64

    – Harry Chittenden
    Nov 13 '18 at 16:39











  • HORIZ is a 2d array, (2400,2400). Have you tried calling this with (horiz, vert) instead?

    – hpaulj
    Nov 13 '18 at 16:49






  • 1





    If you give us a Minimal, Complete, and Verifiable example, something we can copy-n-paste and run, we might be able to help more.

    – hpaulj
    Nov 13 '18 at 17:10

















Just to be clear, what is data.shape and data.dtype? You need to show some of that data checking.

– hpaulj
Nov 13 '18 at 16:31







Just to be clear, what is data.shape and data.dtype? You need to show some of that data checking.

– hpaulj
Nov 13 '18 at 16:31















Shape is (2400, 2400).

– Harry Chittenden
Nov 13 '18 at 16:39





Shape is (2400, 2400).

– Harry Chittenden
Nov 13 '18 at 16:39













dtype is float64

– Harry Chittenden
Nov 13 '18 at 16:39





dtype is float64

– Harry Chittenden
Nov 13 '18 at 16:39













HORIZ is a 2d array, (2400,2400). Have you tried calling this with (horiz, vert) instead?

– hpaulj
Nov 13 '18 at 16:49





HORIZ is a 2d array, (2400,2400). Have you tried calling this with (horiz, vert) instead?

– hpaulj
Nov 13 '18 at 16:49




1




1





If you give us a Minimal, Complete, and Verifiable example, something we can copy-n-paste and run, we might be able to help more.

– hpaulj
Nov 13 '18 at 17:10





If you give us a Minimal, Complete, and Verifiable example, something we can copy-n-paste and run, we might be able to help more.

– hpaulj
Nov 13 '18 at 17:10












2 Answers
2






active

oldest

votes


















0














Per the comments, here is a 3D surface fitter using curve_fit() that has 3D scatterplot, 3D surface plot, and contour plot.



import numpy, scipy, scipy.optimize
import matplotlib
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm # to colormap 3D surfaces from blue to red
import matplotlib.pyplot as plt

graphWidth = 800 # units are pixels
graphHeight = 600 # units are pixels

# 3D contour plot lines
numberOfContourLines = 16


def SurfacePlot(func, data, fittedParameters):
f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)

matplotlib.pyplot.grid(True)
axes = Axes3D(f)

x_data = data[0]
y_data = data[1]
z_data = data[2]

xModel = numpy.linspace(min(x_data), max(x_data), 20)
yModel = numpy.linspace(min(y_data), max(y_data), 20)
X, Y = numpy.meshgrid(xModel, yModel)

Z = func(numpy.array([X, Y]), *fittedParameters)

axes.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=1, antialiased=True)

axes.scatter(x_data, y_data, z_data) # show data along with plotted surface

axes.set_title('Surface Plot (click-drag with mouse)') # add a title for surface plot
axes.set_xlabel('X Data') # X axis data label
axes.set_ylabel('Y Data') # Y axis data label
axes.set_zlabel('Z Data') # Z axis data label

plt.show()
plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


def ContourPlot(func, data, fittedParameters):
f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)
axes = f.add_subplot(111)

x_data = data[0]
y_data = data[1]
z_data = data[2]

xModel = numpy.linspace(min(x_data), max(x_data), 20)
yModel = numpy.linspace(min(y_data), max(y_data), 20)
X, Y = numpy.meshgrid(xModel, yModel)

Z = func(numpy.array([X, Y]), *fittedParameters)

axes.plot(x_data, y_data, 'o')

axes.set_title('Contour Plot') # add a title for contour plot
axes.set_xlabel('X Data') # X axis data label
axes.set_ylabel('Y Data') # Y axis data label

CS = matplotlib.pyplot.contour(X, Y, Z, numberOfContourLines, colors='k')
matplotlib.pyplot.clabel(CS, inline=1, fontsize=10) # labels for contours

plt.show()
plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


def ScatterPlot(data):
f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)

matplotlib.pyplot.grid(True)
axes = Axes3D(f)
x_data = data[0]
y_data = data[1]
z_data = data[2]

axes.scatter(x_data, y_data, z_data)

axes.set_title('Scatter Plot (click-drag with mouse)')
axes.set_xlabel('X Data')
axes.set_ylabel('Y Data')
axes.set_zlabel('Z Data')

plt.show()
plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


def func(data, a, alpha, beta):
t = data[0]
p_p = data[1]
return a * (t**alpha) * (p_p**beta)


if __name__ == "__main__":
xData = numpy.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0])
yData = numpy.array([11.0, 12.1, 13.0, 14.1, 15.0, 16.1, 17.0, 18.1, 90.0])
zData = numpy.array([1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.0, 9.9])

data = [xData, yData, zData]

initialParameters = [1.0, 1.0, 1.0] # these are the same as scipy default values in this example

# here a non-linear surface fit is made with scipy's curve_fit()
fittedParameters, pcov = scipy.optimize.curve_fit(func, [xData, yData], zData, p0 = initialParameters)

ScatterPlot(data)
SurfacePlot(func, data, fittedParameters)
ContourPlot(func, data, fittedParameters)

print('fitted prameters', fittedParameters)

modelPredictions = func(data, *fittedParameters)

absError = modelPredictions - zData

SE = numpy.square(absError) # squared errors
MSE = numpy.mean(SE) # mean squared errors
RMSE = numpy.sqrt(MSE) # Root Mean Squared Error, RMSE
Rsquared = 1.0 - (numpy.var(absError) / numpy.var(zData))
print('RMSE:', RMSE)
print('R-squared:', Rsquared)





share|improve this answer































    0














    OK guys, I've fixed the problem myself. As I suspected, it's a dimensionality issue.



    The appropriate dimensions for curve_fit applied to a 2D array are as follows:





    • Function - One Dimension, which in this case carries the same dimensions as the data set unless enforced


    • x data - (2, n*m), where n and m are the dimensions of the data array


    • y data - (n*m)


    • List of Initial Parameters - A 1D array simply containing all the parameters in the same order as stated in the function


    I therefore left my parameter array unchanged, but made the following change to the function:



    def Gauss2D(x, mux, muy, sigmax, sigmay, amplitude, offset, rotation):
    assert len(x) == 2
    X = x[0]
    Y = x[1]
    A = (np.cos(rotation)**2)/(2*sigmax**2) + (np.sin(rotation)**2)/(2*sigmay**2)
    B = (np.sin(rotation*2))/(4*sigmay**2) - (np.sin(2*rotation))/(4*sigmax**2)
    C = (np.sin(rotation)**2)/(2*sigmax**2) + (np.cos(rotation)**2)/(2*sigmay**2)
    G = amplitude*np.exp(-((A * (X - mux) ** 2) + (2 * B * (X - mux) * (Y - muy)) + (C * (Y - muy) ** 2))) + offset
    return G.ravel()


    and I passed the following to the x data argument:



    x = np.vstack((HORIZ.ravel(), VERT.ravel()))


    and this to the y data argument:



    y = data.ravel()


    Thus, I optimised it using:



    curve_fit(Gauss2D, x, y, po)


    which works just fine.






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284842%2fscipy-curve-fit-for-two-dimensions-not-working-object-too-deep%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      0














      Per the comments, here is a 3D surface fitter using curve_fit() that has 3D scatterplot, 3D surface plot, and contour plot.



      import numpy, scipy, scipy.optimize
      import matplotlib
      from mpl_toolkits.mplot3d import Axes3D
      from matplotlib import cm # to colormap 3D surfaces from blue to red
      import matplotlib.pyplot as plt

      graphWidth = 800 # units are pixels
      graphHeight = 600 # units are pixels

      # 3D contour plot lines
      numberOfContourLines = 16


      def SurfacePlot(func, data, fittedParameters):
      f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)

      matplotlib.pyplot.grid(True)
      axes = Axes3D(f)

      x_data = data[0]
      y_data = data[1]
      z_data = data[2]

      xModel = numpy.linspace(min(x_data), max(x_data), 20)
      yModel = numpy.linspace(min(y_data), max(y_data), 20)
      X, Y = numpy.meshgrid(xModel, yModel)

      Z = func(numpy.array([X, Y]), *fittedParameters)

      axes.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=1, antialiased=True)

      axes.scatter(x_data, y_data, z_data) # show data along with plotted surface

      axes.set_title('Surface Plot (click-drag with mouse)') # add a title for surface plot
      axes.set_xlabel('X Data') # X axis data label
      axes.set_ylabel('Y Data') # Y axis data label
      axes.set_zlabel('Z Data') # Z axis data label

      plt.show()
      plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


      def ContourPlot(func, data, fittedParameters):
      f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)
      axes = f.add_subplot(111)

      x_data = data[0]
      y_data = data[1]
      z_data = data[2]

      xModel = numpy.linspace(min(x_data), max(x_data), 20)
      yModel = numpy.linspace(min(y_data), max(y_data), 20)
      X, Y = numpy.meshgrid(xModel, yModel)

      Z = func(numpy.array([X, Y]), *fittedParameters)

      axes.plot(x_data, y_data, 'o')

      axes.set_title('Contour Plot') # add a title for contour plot
      axes.set_xlabel('X Data') # X axis data label
      axes.set_ylabel('Y Data') # Y axis data label

      CS = matplotlib.pyplot.contour(X, Y, Z, numberOfContourLines, colors='k')
      matplotlib.pyplot.clabel(CS, inline=1, fontsize=10) # labels for contours

      plt.show()
      plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


      def ScatterPlot(data):
      f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)

      matplotlib.pyplot.grid(True)
      axes = Axes3D(f)
      x_data = data[0]
      y_data = data[1]
      z_data = data[2]

      axes.scatter(x_data, y_data, z_data)

      axes.set_title('Scatter Plot (click-drag with mouse)')
      axes.set_xlabel('X Data')
      axes.set_ylabel('Y Data')
      axes.set_zlabel('Z Data')

      plt.show()
      plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


      def func(data, a, alpha, beta):
      t = data[0]
      p_p = data[1]
      return a * (t**alpha) * (p_p**beta)


      if __name__ == "__main__":
      xData = numpy.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0])
      yData = numpy.array([11.0, 12.1, 13.0, 14.1, 15.0, 16.1, 17.0, 18.1, 90.0])
      zData = numpy.array([1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.0, 9.9])

      data = [xData, yData, zData]

      initialParameters = [1.0, 1.0, 1.0] # these are the same as scipy default values in this example

      # here a non-linear surface fit is made with scipy's curve_fit()
      fittedParameters, pcov = scipy.optimize.curve_fit(func, [xData, yData], zData, p0 = initialParameters)

      ScatterPlot(data)
      SurfacePlot(func, data, fittedParameters)
      ContourPlot(func, data, fittedParameters)

      print('fitted prameters', fittedParameters)

      modelPredictions = func(data, *fittedParameters)

      absError = modelPredictions - zData

      SE = numpy.square(absError) # squared errors
      MSE = numpy.mean(SE) # mean squared errors
      RMSE = numpy.sqrt(MSE) # Root Mean Squared Error, RMSE
      Rsquared = 1.0 - (numpy.var(absError) / numpy.var(zData))
      print('RMSE:', RMSE)
      print('R-squared:', Rsquared)





      share|improve this answer




























        0














        Per the comments, here is a 3D surface fitter using curve_fit() that has 3D scatterplot, 3D surface plot, and contour plot.



        import numpy, scipy, scipy.optimize
        import matplotlib
        from mpl_toolkits.mplot3d import Axes3D
        from matplotlib import cm # to colormap 3D surfaces from blue to red
        import matplotlib.pyplot as plt

        graphWidth = 800 # units are pixels
        graphHeight = 600 # units are pixels

        # 3D contour plot lines
        numberOfContourLines = 16


        def SurfacePlot(func, data, fittedParameters):
        f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)

        matplotlib.pyplot.grid(True)
        axes = Axes3D(f)

        x_data = data[0]
        y_data = data[1]
        z_data = data[2]

        xModel = numpy.linspace(min(x_data), max(x_data), 20)
        yModel = numpy.linspace(min(y_data), max(y_data), 20)
        X, Y = numpy.meshgrid(xModel, yModel)

        Z = func(numpy.array([X, Y]), *fittedParameters)

        axes.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=1, antialiased=True)

        axes.scatter(x_data, y_data, z_data) # show data along with plotted surface

        axes.set_title('Surface Plot (click-drag with mouse)') # add a title for surface plot
        axes.set_xlabel('X Data') # X axis data label
        axes.set_ylabel('Y Data') # Y axis data label
        axes.set_zlabel('Z Data') # Z axis data label

        plt.show()
        plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


        def ContourPlot(func, data, fittedParameters):
        f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)
        axes = f.add_subplot(111)

        x_data = data[0]
        y_data = data[1]
        z_data = data[2]

        xModel = numpy.linspace(min(x_data), max(x_data), 20)
        yModel = numpy.linspace(min(y_data), max(y_data), 20)
        X, Y = numpy.meshgrid(xModel, yModel)

        Z = func(numpy.array([X, Y]), *fittedParameters)

        axes.plot(x_data, y_data, 'o')

        axes.set_title('Contour Plot') # add a title for contour plot
        axes.set_xlabel('X Data') # X axis data label
        axes.set_ylabel('Y Data') # Y axis data label

        CS = matplotlib.pyplot.contour(X, Y, Z, numberOfContourLines, colors='k')
        matplotlib.pyplot.clabel(CS, inline=1, fontsize=10) # labels for contours

        plt.show()
        plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


        def ScatterPlot(data):
        f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)

        matplotlib.pyplot.grid(True)
        axes = Axes3D(f)
        x_data = data[0]
        y_data = data[1]
        z_data = data[2]

        axes.scatter(x_data, y_data, z_data)

        axes.set_title('Scatter Plot (click-drag with mouse)')
        axes.set_xlabel('X Data')
        axes.set_ylabel('Y Data')
        axes.set_zlabel('Z Data')

        plt.show()
        plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


        def func(data, a, alpha, beta):
        t = data[0]
        p_p = data[1]
        return a * (t**alpha) * (p_p**beta)


        if __name__ == "__main__":
        xData = numpy.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0])
        yData = numpy.array([11.0, 12.1, 13.0, 14.1, 15.0, 16.1, 17.0, 18.1, 90.0])
        zData = numpy.array([1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.0, 9.9])

        data = [xData, yData, zData]

        initialParameters = [1.0, 1.0, 1.0] # these are the same as scipy default values in this example

        # here a non-linear surface fit is made with scipy's curve_fit()
        fittedParameters, pcov = scipy.optimize.curve_fit(func, [xData, yData], zData, p0 = initialParameters)

        ScatterPlot(data)
        SurfacePlot(func, data, fittedParameters)
        ContourPlot(func, data, fittedParameters)

        print('fitted prameters', fittedParameters)

        modelPredictions = func(data, *fittedParameters)

        absError = modelPredictions - zData

        SE = numpy.square(absError) # squared errors
        MSE = numpy.mean(SE) # mean squared errors
        RMSE = numpy.sqrt(MSE) # Root Mean Squared Error, RMSE
        Rsquared = 1.0 - (numpy.var(absError) / numpy.var(zData))
        print('RMSE:', RMSE)
        print('R-squared:', Rsquared)





        share|improve this answer


























          0












          0








          0







          Per the comments, here is a 3D surface fitter using curve_fit() that has 3D scatterplot, 3D surface plot, and contour plot.



          import numpy, scipy, scipy.optimize
          import matplotlib
          from mpl_toolkits.mplot3d import Axes3D
          from matplotlib import cm # to colormap 3D surfaces from blue to red
          import matplotlib.pyplot as plt

          graphWidth = 800 # units are pixels
          graphHeight = 600 # units are pixels

          # 3D contour plot lines
          numberOfContourLines = 16


          def SurfacePlot(func, data, fittedParameters):
          f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)

          matplotlib.pyplot.grid(True)
          axes = Axes3D(f)

          x_data = data[0]
          y_data = data[1]
          z_data = data[2]

          xModel = numpy.linspace(min(x_data), max(x_data), 20)
          yModel = numpy.linspace(min(y_data), max(y_data), 20)
          X, Y = numpy.meshgrid(xModel, yModel)

          Z = func(numpy.array([X, Y]), *fittedParameters)

          axes.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=1, antialiased=True)

          axes.scatter(x_data, y_data, z_data) # show data along with plotted surface

          axes.set_title('Surface Plot (click-drag with mouse)') # add a title for surface plot
          axes.set_xlabel('X Data') # X axis data label
          axes.set_ylabel('Y Data') # Y axis data label
          axes.set_zlabel('Z Data') # Z axis data label

          plt.show()
          plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


          def ContourPlot(func, data, fittedParameters):
          f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)
          axes = f.add_subplot(111)

          x_data = data[0]
          y_data = data[1]
          z_data = data[2]

          xModel = numpy.linspace(min(x_data), max(x_data), 20)
          yModel = numpy.linspace(min(y_data), max(y_data), 20)
          X, Y = numpy.meshgrid(xModel, yModel)

          Z = func(numpy.array([X, Y]), *fittedParameters)

          axes.plot(x_data, y_data, 'o')

          axes.set_title('Contour Plot') # add a title for contour plot
          axes.set_xlabel('X Data') # X axis data label
          axes.set_ylabel('Y Data') # Y axis data label

          CS = matplotlib.pyplot.contour(X, Y, Z, numberOfContourLines, colors='k')
          matplotlib.pyplot.clabel(CS, inline=1, fontsize=10) # labels for contours

          plt.show()
          plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


          def ScatterPlot(data):
          f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)

          matplotlib.pyplot.grid(True)
          axes = Axes3D(f)
          x_data = data[0]
          y_data = data[1]
          z_data = data[2]

          axes.scatter(x_data, y_data, z_data)

          axes.set_title('Scatter Plot (click-drag with mouse)')
          axes.set_xlabel('X Data')
          axes.set_ylabel('Y Data')
          axes.set_zlabel('Z Data')

          plt.show()
          plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


          def func(data, a, alpha, beta):
          t = data[0]
          p_p = data[1]
          return a * (t**alpha) * (p_p**beta)


          if __name__ == "__main__":
          xData = numpy.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0])
          yData = numpy.array([11.0, 12.1, 13.0, 14.1, 15.0, 16.1, 17.0, 18.1, 90.0])
          zData = numpy.array([1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.0, 9.9])

          data = [xData, yData, zData]

          initialParameters = [1.0, 1.0, 1.0] # these are the same as scipy default values in this example

          # here a non-linear surface fit is made with scipy's curve_fit()
          fittedParameters, pcov = scipy.optimize.curve_fit(func, [xData, yData], zData, p0 = initialParameters)

          ScatterPlot(data)
          SurfacePlot(func, data, fittedParameters)
          ContourPlot(func, data, fittedParameters)

          print('fitted prameters', fittedParameters)

          modelPredictions = func(data, *fittedParameters)

          absError = modelPredictions - zData

          SE = numpy.square(absError) # squared errors
          MSE = numpy.mean(SE) # mean squared errors
          RMSE = numpy.sqrt(MSE) # Root Mean Squared Error, RMSE
          Rsquared = 1.0 - (numpy.var(absError) / numpy.var(zData))
          print('RMSE:', RMSE)
          print('R-squared:', Rsquared)





          share|improve this answer













          Per the comments, here is a 3D surface fitter using curve_fit() that has 3D scatterplot, 3D surface plot, and contour plot.



          import numpy, scipy, scipy.optimize
          import matplotlib
          from mpl_toolkits.mplot3d import Axes3D
          from matplotlib import cm # to colormap 3D surfaces from blue to red
          import matplotlib.pyplot as plt

          graphWidth = 800 # units are pixels
          graphHeight = 600 # units are pixels

          # 3D contour plot lines
          numberOfContourLines = 16


          def SurfacePlot(func, data, fittedParameters):
          f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)

          matplotlib.pyplot.grid(True)
          axes = Axes3D(f)

          x_data = data[0]
          y_data = data[1]
          z_data = data[2]

          xModel = numpy.linspace(min(x_data), max(x_data), 20)
          yModel = numpy.linspace(min(y_data), max(y_data), 20)
          X, Y = numpy.meshgrid(xModel, yModel)

          Z = func(numpy.array([X, Y]), *fittedParameters)

          axes.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=1, antialiased=True)

          axes.scatter(x_data, y_data, z_data) # show data along with plotted surface

          axes.set_title('Surface Plot (click-drag with mouse)') # add a title for surface plot
          axes.set_xlabel('X Data') # X axis data label
          axes.set_ylabel('Y Data') # Y axis data label
          axes.set_zlabel('Z Data') # Z axis data label

          plt.show()
          plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


          def ContourPlot(func, data, fittedParameters):
          f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)
          axes = f.add_subplot(111)

          x_data = data[0]
          y_data = data[1]
          z_data = data[2]

          xModel = numpy.linspace(min(x_data), max(x_data), 20)
          yModel = numpy.linspace(min(y_data), max(y_data), 20)
          X, Y = numpy.meshgrid(xModel, yModel)

          Z = func(numpy.array([X, Y]), *fittedParameters)

          axes.plot(x_data, y_data, 'o')

          axes.set_title('Contour Plot') # add a title for contour plot
          axes.set_xlabel('X Data') # X axis data label
          axes.set_ylabel('Y Data') # Y axis data label

          CS = matplotlib.pyplot.contour(X, Y, Z, numberOfContourLines, colors='k')
          matplotlib.pyplot.clabel(CS, inline=1, fontsize=10) # labels for contours

          plt.show()
          plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


          def ScatterPlot(data):
          f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)

          matplotlib.pyplot.grid(True)
          axes = Axes3D(f)
          x_data = data[0]
          y_data = data[1]
          z_data = data[2]

          axes.scatter(x_data, y_data, z_data)

          axes.set_title('Scatter Plot (click-drag with mouse)')
          axes.set_xlabel('X Data')
          axes.set_ylabel('Y Data')
          axes.set_zlabel('Z Data')

          plt.show()
          plt.close('all') # clean up after using pyplot or else thaere can be memory and process problems


          def func(data, a, alpha, beta):
          t = data[0]
          p_p = data[1]
          return a * (t**alpha) * (p_p**beta)


          if __name__ == "__main__":
          xData = numpy.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0])
          yData = numpy.array([11.0, 12.1, 13.0, 14.1, 15.0, 16.1, 17.0, 18.1, 90.0])
          zData = numpy.array([1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.0, 9.9])

          data = [xData, yData, zData]

          initialParameters = [1.0, 1.0, 1.0] # these are the same as scipy default values in this example

          # here a non-linear surface fit is made with scipy's curve_fit()
          fittedParameters, pcov = scipy.optimize.curve_fit(func, [xData, yData], zData, p0 = initialParameters)

          ScatterPlot(data)
          SurfacePlot(func, data, fittedParameters)
          ContourPlot(func, data, fittedParameters)

          print('fitted prameters', fittedParameters)

          modelPredictions = func(data, *fittedParameters)

          absError = modelPredictions - zData

          SE = numpy.square(absError) # squared errors
          MSE = numpy.mean(SE) # mean squared errors
          RMSE = numpy.sqrt(MSE) # Root Mean Squared Error, RMSE
          Rsquared = 1.0 - (numpy.var(absError) / numpy.var(zData))
          print('RMSE:', RMSE)
          print('R-squared:', Rsquared)






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 13 '18 at 23:42









          James PhillipsJames Phillips

          1,509387




          1,509387

























              0














              OK guys, I've fixed the problem myself. As I suspected, it's a dimensionality issue.



              The appropriate dimensions for curve_fit applied to a 2D array are as follows:





              • Function - One Dimension, which in this case carries the same dimensions as the data set unless enforced


              • x data - (2, n*m), where n and m are the dimensions of the data array


              • y data - (n*m)


              • List of Initial Parameters - A 1D array simply containing all the parameters in the same order as stated in the function


              I therefore left my parameter array unchanged, but made the following change to the function:



              def Gauss2D(x, mux, muy, sigmax, sigmay, amplitude, offset, rotation):
              assert len(x) == 2
              X = x[0]
              Y = x[1]
              A = (np.cos(rotation)**2)/(2*sigmax**2) + (np.sin(rotation)**2)/(2*sigmay**2)
              B = (np.sin(rotation*2))/(4*sigmay**2) - (np.sin(2*rotation))/(4*sigmax**2)
              C = (np.sin(rotation)**2)/(2*sigmax**2) + (np.cos(rotation)**2)/(2*sigmay**2)
              G = amplitude*np.exp(-((A * (X - mux) ** 2) + (2 * B * (X - mux) * (Y - muy)) + (C * (Y - muy) ** 2))) + offset
              return G.ravel()


              and I passed the following to the x data argument:



              x = np.vstack((HORIZ.ravel(), VERT.ravel()))


              and this to the y data argument:



              y = data.ravel()


              Thus, I optimised it using:



              curve_fit(Gauss2D, x, y, po)


              which works just fine.






              share|improve this answer




























                0














                OK guys, I've fixed the problem myself. As I suspected, it's a dimensionality issue.



                The appropriate dimensions for curve_fit applied to a 2D array are as follows:





                • Function - One Dimension, which in this case carries the same dimensions as the data set unless enforced


                • x data - (2, n*m), where n and m are the dimensions of the data array


                • y data - (n*m)


                • List of Initial Parameters - A 1D array simply containing all the parameters in the same order as stated in the function


                I therefore left my parameter array unchanged, but made the following change to the function:



                def Gauss2D(x, mux, muy, sigmax, sigmay, amplitude, offset, rotation):
                assert len(x) == 2
                X = x[0]
                Y = x[1]
                A = (np.cos(rotation)**2)/(2*sigmax**2) + (np.sin(rotation)**2)/(2*sigmay**2)
                B = (np.sin(rotation*2))/(4*sigmay**2) - (np.sin(2*rotation))/(4*sigmax**2)
                C = (np.sin(rotation)**2)/(2*sigmax**2) + (np.cos(rotation)**2)/(2*sigmay**2)
                G = amplitude*np.exp(-((A * (X - mux) ** 2) + (2 * B * (X - mux) * (Y - muy)) + (C * (Y - muy) ** 2))) + offset
                return G.ravel()


                and I passed the following to the x data argument:



                x = np.vstack((HORIZ.ravel(), VERT.ravel()))


                and this to the y data argument:



                y = data.ravel()


                Thus, I optimised it using:



                curve_fit(Gauss2D, x, y, po)


                which works just fine.






                share|improve this answer


























                  0












                  0








                  0







                  OK guys, I've fixed the problem myself. As I suspected, it's a dimensionality issue.



                  The appropriate dimensions for curve_fit applied to a 2D array are as follows:





                  • Function - One Dimension, which in this case carries the same dimensions as the data set unless enforced


                  • x data - (2, n*m), where n and m are the dimensions of the data array


                  • y data - (n*m)


                  • List of Initial Parameters - A 1D array simply containing all the parameters in the same order as stated in the function


                  I therefore left my parameter array unchanged, but made the following change to the function:



                  def Gauss2D(x, mux, muy, sigmax, sigmay, amplitude, offset, rotation):
                  assert len(x) == 2
                  X = x[0]
                  Y = x[1]
                  A = (np.cos(rotation)**2)/(2*sigmax**2) + (np.sin(rotation)**2)/(2*sigmay**2)
                  B = (np.sin(rotation*2))/(4*sigmay**2) - (np.sin(2*rotation))/(4*sigmax**2)
                  C = (np.sin(rotation)**2)/(2*sigmax**2) + (np.cos(rotation)**2)/(2*sigmay**2)
                  G = amplitude*np.exp(-((A * (X - mux) ** 2) + (2 * B * (X - mux) * (Y - muy)) + (C * (Y - muy) ** 2))) + offset
                  return G.ravel()


                  and I passed the following to the x data argument:



                  x = np.vstack((HORIZ.ravel(), VERT.ravel()))


                  and this to the y data argument:



                  y = data.ravel()


                  Thus, I optimised it using:



                  curve_fit(Gauss2D, x, y, po)


                  which works just fine.






                  share|improve this answer













                  OK guys, I've fixed the problem myself. As I suspected, it's a dimensionality issue.



                  The appropriate dimensions for curve_fit applied to a 2D array are as follows:





                  • Function - One Dimension, which in this case carries the same dimensions as the data set unless enforced


                  • x data - (2, n*m), where n and m are the dimensions of the data array


                  • y data - (n*m)


                  • List of Initial Parameters - A 1D array simply containing all the parameters in the same order as stated in the function


                  I therefore left my parameter array unchanged, but made the following change to the function:



                  def Gauss2D(x, mux, muy, sigmax, sigmay, amplitude, offset, rotation):
                  assert len(x) == 2
                  X = x[0]
                  Y = x[1]
                  A = (np.cos(rotation)**2)/(2*sigmax**2) + (np.sin(rotation)**2)/(2*sigmay**2)
                  B = (np.sin(rotation*2))/(4*sigmay**2) - (np.sin(2*rotation))/(4*sigmax**2)
                  C = (np.sin(rotation)**2)/(2*sigmax**2) + (np.cos(rotation)**2)/(2*sigmay**2)
                  G = amplitude*np.exp(-((A * (X - mux) ** 2) + (2 * B * (X - mux) * (Y - muy)) + (C * (Y - muy) ** 2))) + offset
                  return G.ravel()


                  and I passed the following to the x data argument:



                  x = np.vstack((HORIZ.ravel(), VERT.ravel()))


                  and this to the y data argument:



                  y = data.ravel()


                  Thus, I optimised it using:



                  curve_fit(Gauss2D, x, y, po)


                  which works just fine.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 14 '18 at 12:19









                  Harry ChittendenHarry Chittenden

                  62




                  62






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284842%2fscipy-curve-fit-for-two-dimensions-not-working-object-too-deep%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Full-time equivalent

                      Bicuculline

                      さくらももこ