Scipy's

     curve_fit() 

uses iterations to search for optimal parameters. If the number of iterations exceeds the default number of 800, but the optimal parameters are still not found, then this error will be raised.

    Optimal parameters not found: Number of calls to function has reached maxfev = 800

You can provide some initial guess parameters for curve_fit(), then try again. Or, you can increase the allowable iterations. Or do both!

Here is an example:

    popt, pcov = curve_fit(exponenial_func, x, y, p0=[1,0,1], maxfev=5000)

p0 is the guess

maxfev is the max number of iterations

You can also try setting bounds which will help the function find the solution. However, you cannot set bounds and a max_nfev at the same time.

    popt, pcov = curve_fit(exponenial_func, x, y, p0=[1,0,1], bounds=(1,3))

Source1: https://github.com/scipy/scipy/issues/6340

Source2: My own testing and finding that the about github is not 100% accurate

Also, other recommendations about not using 0 as an 'x' value are great recommendations. Start your 'x' array with 1 to avoid divide by zero errors.

Answer from embulldogs99 on Stack Overflow
🌐
GitHub
github.com › scipy › scipy › issues › 6340
Curve_fit bounds and maxfev · Issue #6340 · scipy/scipy
July 1, 2016 - import numpy as np from scipy.optimize import curve_fit x = np.arange(0,10) y = 2*x curve_fit(lambda x,p: p*x, x, y, maxfev=100) curve_fit(lambda x,p: p*x, x, y, bounds=(0,3), maxfev=100)
Author   vascotenner
🌐
SciPy
docs.scipy.org › doc › scipy › reference › generated › scipy.optimize.curve_fit.html
curve_fit — SciPy v1.17.0 Manual
Parameters to be fitted must have similar scale. Differences of multiple orders of magnitude can lead to incorrect results. For the ‘trf’ and ‘dogbox’ methods, the x_scale keyword argument can be used to scale the parameters. curve_fit is for local optimization of parameters to minimize ...
Discussions

python - Why does scipy.optimize.curve_fit not fit correctly to the data? - Stack Overflow
@Juh_ I chose curve_fit because I do not know an alternative to it. Maybe you can tell me, which optimizer would be a better one. Thanks ... The point of my questions were on the choice of optimization with respect to the problem to optimize (f&data). The answer of Greg is good. ... Firstly try not to increase maxfev ... More on stackoverflow.com
🌐 stackoverflow.com
Fitting using curve_fit of scipy in python gives totally different answer for 1/t and t - Computational Science Stack Exchange
I was trying to fit some data to a single degree exponential decay function but a*exp(-x*t) and a*exp(-x/t) gives completely different answers with the latter not at all fitting the data well. The ... More on scicomp.stackexchange.com
🌐 scicomp.stackexchange.com
June 12, 2021
curve fitting - What does 'maxfev' do in iPython Notebook? - Stack Overflow
I was using the curve_fit function to find two coefficients and could not get a result until I altered something called maxfev to be a much larger value, since my error was that 'maxfev=600 has been More on stackoverflow.com
🌐 stackoverflow.com
Handle scipy fitting errors in `xarray.curve_fit`
Is your feature request related to a problem? I'm trying to fit a bunch of exponential decays to a dataset of dimensions (Time, experimental_index), along the Time dimension. This works nicely... e... More on github.com
🌐 github.com
2
March 2, 2022
Top answer
1 of 4
44

Scipy's

     curve_fit() 

uses iterations to search for optimal parameters. If the number of iterations exceeds the default number of 800, but the optimal parameters are still not found, then this error will be raised.

    Optimal parameters not found: Number of calls to function has reached maxfev = 800

You can provide some initial guess parameters for curve_fit(), then try again. Or, you can increase the allowable iterations. Or do both!

Here is an example:

    popt, pcov = curve_fit(exponenial_func, x, y, p0=[1,0,1], maxfev=5000)

p0 is the guess

maxfev is the max number of iterations

You can also try setting bounds which will help the function find the solution. However, you cannot set bounds and a max_nfev at the same time.

    popt, pcov = curve_fit(exponenial_func, x, y, p0=[1,0,1], bounds=(1,3))

Source1: https://github.com/scipy/scipy/issues/6340

Source2: My own testing and finding that the about github is not 100% accurate

Also, other recommendations about not using 0 as an 'x' value are great recommendations. Start your 'x' array with 1 to avoid divide by zero errors.

2 of 4
24

Your original data is t1 and F1. Therefore curve_fit should be given t1 as its second argument, not t.

popt, pcov = curve_fit(func, t1, F1, maxfev=1000)

Now once you obtain fitted parameters, popt, you can evaluate func at the points in t to obtain a fitted curve:

t = np.linspace(1, 3600 * 24 * 28, 13)
plt.plot(t, func(t, *popt), label="Fitted Curve")

(I removed zero from t (per StuGrey's answer) to avoid the Warning: divide by zero encountered in log.)


import matplotlib.pyplot as plt
import scipy.optimize as optimize
import numpy as np

# data
F1 = np.array([
    735.0, 696.0, 690.0, 683.0, 680.0, 678.0, 679.0, 675.0, 671.0, 669.0, 668.0,
    664.0, 664.0])
t1 = np.array([
    1, 90000.0, 178200.0, 421200.0, 505800.0, 592200.0, 768600.0, 1036800.0,
    1371600.0, 1630800.0, 1715400.0, 2345400.0, 2409012.0])

plt.plot(t1, F1, 'ro', label="original data")

# curvefit

def func(t, a, b):
    return a + b * np.log(t)

popt, pcov = optimize.curve_fit(func, t1, F1, maxfev=1000)
t = np.linspace(1, 3600 * 24 * 28, 13)
plt.plot(t, func(t, *popt), label="Fitted Curve")
plt.legend(loc='upper left')
plt.show()

🌐
Medium
medium.com › @whyamit101 › understanding-curve-fit-in-numpy-c31bab4264af
Understanding curve_fit() in NumPy | by why amit | Medium
February 26, 2025 - ... Why? Poor initial guesses or bad data scaling. Fix: Try scaling your data or adjusting the maxfev (maximum function evaluations): popt, pcov = curve_fit(exp_func, x, y, maxfev=10000)
🌐
University of Toronto
physics.utoronto.ca › apl › python › curve_fit_to_data.py
curve_fit_to_data.py
# Note: Try replacing 1171 by 1170 and see what happens. try: p, cov = scipy.optimize.curve_fit( func, x_data, y_data, p0=p_guess, sigma=y_sigma, maxfev=100*(len(x_data)+1)) # Notes: maxfev is the maximum number of func evaluations tried; you # can try increasing this value if the fit fails.
Find elsewhere
🌐
Alteryx Community
community.alteryx.com › t5 › Alteryx-Designer-Desktop-Discussions › python-curve-fit-quot-Optimal-parameters-not-found-quot › td-p › 849220
Solved: python curve_fit "Optimal parameters not found" - Alteryx Community
November 23, 2021 - When i try to run the same function on a subset of the data ([GroupBy = 'SFB'), the function either fails completely, or it gives me a curve that isnt fitted to the data at all. This is the error: "RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 800."
🌐
GitHub
github.com › pydata › xarray › issues › 6317
Handle scipy fitting errors in `xarray.curve_fit` · Issue #6317 · pydata/xarray
March 2, 2022 - fits = [] for experimental_index in timetraces.experimental_index: trace = traces.sel(experimental_index=experimental_index) try: fit = trace.curvefit( "Time", fitfunc, p0=(...), bounds={...}, ) except (RuntimeError, TypeError) as e: logger.debug(...) continue fits.append(fit) fits = xarray.concat(fits, dim="experimental_index", coords="all")
Author   StanczakDominik
🌐
Reddit
reddit.com › r/learnpython › how to specify number of *args? (having problems using curve_fit when creating a polynomial model)
r/learnpython on Reddit: How to specify number of *args? (Having problems using curve_fit when creating a polynomial model)
December 24, 2017 -

--- SOLVED ----

u/Standardw and u/kra_pao provided me with the answers: Passing an array-like initial set of parameters to curve_fit helps, i.e.:

# define start values for scalar parameters (so that len(args) is known)
p = [1] * len(expList)

# fit data to model
popt, pcov = curve_fit(polymodel, xSamples, valSamps,  p0 = p, maxfev = 10000)

However, with this, there is a warning message from curve_fit. This new problem seems to originate in my polynomial model. I will work on that and of course post the solution here.

UPDATE:

Fixed it completely and posted resulting code in my comment below.

Original Post:

Hi r/learnpython!

This subreddit has really helped me a lot and continues to do so when I'm trying to code something in python. Thank you all for your great posts!

Now I turn to you for help.

Context

I'm working on my thesis (mechanical engineering, so I don't know a lot about computers or programming). In a nutshell, I'm trying out different ways to optimize the shape of a mechanical structure and compare multiple optimization techniques. Python is the language to go to for that because it's easily automatable, can directly start my FEM programs with alternative parameters and so on. The code will not be published.

My Specific Problem

I have some sample data that I want to fit to a polynomial model. What I'm too stupid for: I can't figure out how to "create the model" during running the program so that it fits my requirements (i.e. number of dimensions and maximum degree). I tried to boil it down a bit, so as an example I use the ackley function here.

So I have sample data (x, y and function values) of the ackley function and want to fit a model to it. (This level of inaccuaracy is fine - I just need the minimum or can worry about the accuaracy later)

When I use the function also as a model, it works. That's how I got the model in the second picture. When I try to dynamically build the model (sorry, I don't know how to express it better), the code fails:

ValueError: Unable to determine number of fit parameters.

This makes sense: I don't specify the number of *args. I do understand that. But how do I fix it?

The Example Code

Remarks for the functions are below the code block. My problem part is set within "###############" above and below. It's at "# fit data to model".As you can see, I try to define my polynomial model on the run. Doesn't seem elegant to me, I just kind of feel helpless here.

import numpy as np
from itertools import product
from scipy.optimize import curve_fit

def myfunc(x, a=20, b=0.2, c=2*np.pi):
    # ackley function
    d = len(x)
    sumOne = sum([xi**2 for xi in x])
    sumTwo = sum([np.cos(c*xi) for xi in x])
    val = -a * np.exp(-b * np.sqrt(1/d * sumOne)) - np.exp( 1/d * sumTwo) + a + np.exp(1)
    return val


def getpolyexponents(nDim, kDegree):
    """gets the basis function exponents for a polynom"""

    # repeat range {0,...,kDegree} nDim times as rangeSet
    rangeSet = [range(0, kDegree+1) for i in range(0, nDim)]

    # create full product set
    expList = [item for item in product(*rangeSet)]

    # keep only items in list with correct degree,
    # i.e. sum(exponents) <= kDegree            
    expList[:] = [item for item in expList if sum(item) <= kDegree]

    # return the polynom exponents
    return expList

def getbasisfunc(x, exponentSet):
    """gets a single basis function for a polynom with an exponent set"""
    # make list of single elements of basis function, e.g. x^0*y^0, x^0*y^1, ...
    productElements = [x[i]**exponentSet[i] for i in range(0,len(exponentSet))]

    # calculate product of all elements and return it
    val = np.prod(productElements)
    return val

def getbasisfuncarray(x, expList):
    """ builds an array (1-D) of basis functions for a polynom"""
    basisfunclist = [getbasisfunc(x, expList[i]) for i in range(0, len(expList))]
    return np.array(basisfunclist)

def main():    
    # dim d, polynomial degree k
    d = 2
    k = 5
    
    # create n random sample points xSamples in [-5, 5]
    n = 100
    xSamples = np.divide(np.random.randint(-500, 500 + 1, (d,n)), 100)

    # values of samples
    valSamps = myfunc(xSamples)

    # find exponents for polynomial model function
    expList = getpolyexponents(d, k)

    # define model
    def polymodel(x, *args):
        coeffArray = np.array([arg for arg in args])
        basisFuncs = getbasisfuncarray(x, expList)        
        # scalar product / dot product
        poly = np.dot(coeffArray, basisFuncs)
        return poly

################################################
    # fit data to model
    #popt, pcov = curve_fit(polymodel, xSamples, valSamps,  maxfev = 1000) #fails
    popt, pcov = curve_fit(myfunc, xSamples, valSamps,  maxfev = 1000) #works
################################################
    

    # print fitting results
    print("fitting results:")
    print(popt)
    print(pcov)


if __name__ == "__main__": main()
  • myfunc: just the ackley function

  • getpolyexponents: Since I want to create a polynomial model, I need the exponents for all my variables (x1 and x2 or also called x and y in 2-D). For example: In 2D the polynomial basis functions are:

    • x^0*y^0

    • x^0*y^1

    • x^0*y^2

    • x^1*y^0

    • x^1*y^1

    • x^2*y^0

    • I get those exponents from this function. In the 2-D case there would be those 6 sets of exponents in the returned expList

  • getbasisfunc: Uses one exponent set from the expList from above function to create the actual basis function

  • getbasisfuncarray: puts all required basis functions in a 1-D Array.

I did not include the plotting part because it's in another module and would just be more code in here.

If there is a better way to fit my data to a polynomial model of d dimensions (d being up to 23 in my case) and degree k (k up to 10 approx.) with python I am happy to learn new stuff!

Thank you already in advance. Any tips are greatly appreciated!

Cheers

🌐
Softinery
softinery.com › blog › curve-fit-scipy-python
Learn about curve fitting in python (scipy)
February 10, 2025 - Let’s take a look at the line ... (exponential_func), arrays with data (x and y), initial guess (p0) and maximum number of evaluations (maxfev)....
🌐
Notebook Community
notebook.community › juliusf › ipython-notebooks › numerical_analysis › .ipynb_checkpoints › CurveFitting-checkpoint
Curve Fitting using scipy
Look at the error message that results: ----> 2 fitParams, fitCovariances = curve_fit(cap, t, temps) 3 print fitParams 4 print fitCovariances /Volumes/Daiju_1Tb/pauln/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/scipy/optimize/minpack.pyc in curve_fit(f, xdata, ydata, p0, sigma, **kw) 518 if ier not in [1,2,3,4]: 519 msg = "Optimal parameters not found: " + errmsg --> 520 raise RuntimeError(msg) 521 522 if (len(ydata) > len(p0)) and pcov is not None: RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 600.
🌐
Python Guides
pythonguides.com › python-scipy-curve-fit
Python SciPy Curve Fit: Simplify Your Data Analysis With Fitting Methods
June 23, 2025 - This fits an exponential function a·eᵇˣ to the data. This is particularly useful for modeling phenomena like population growth, compound interest, or radioactive decay. ... Sometimes you have prior knowledge about the possible values of your parameters. SciPy allows you to set bounds: import ...
🌐
Stack Overflow
stackoverflow.com › questions › 77264996 › is-there-still-maxfev-parameter-in-curve-fit-if-not-how-can-we-control-the-num
python - Is there still maxfev parameter in curve_fit? If not, how can we control the number of iterations performed? - Stack Overflow
October 10, 2023 - My bad, it should indeed be maxfev and max_nfev. I've checked the doc for 1.7.1 (it still works the same on the stable version though). See the documentation for the **kwargs parameter in the official doc for curve_fit. kwargs get passed to either leastsq (which uses maxfev) or least_squares (uses max_nfev).
🌐
SciPy
docs.scipy.org › doc › scipy › reference › generated › scipy.optimize.leastsq.html
leastsq — SciPy v1.17.0 Manual
The maximum number of calls to the function. If Dfun is provided, then the default maxfev is 100*(N+1) where N is the number of elements in x0, otherwise the default maxfev is 200*(N+1).
🌐
Stack Overflow
stackoverflow.com › questions › 59171944 › why-my-curve-fit-reach-the-maxfev-10000
python - Why my curve_fit reach the maxfev = 10000? - Stack Overflow
December 4, 2019 - try: popt, pcov = curve_fit(kurtosis, xdata, ydata, maxfev= 5000) except: popt = [0,0] D_map[i,r,c] = popt[0] * 1000 K_map[i,r,c] = popt[0]
🌐
Boardflare
boardflare.com › tools › math › curve-fitting › least-squares › curve_fit
CURVE_FIT – Boardflare
# With lm, number of observations (M) must be >= number of parameters (N) if method_value == 'lm' and x_array.shape[0] < n_params: return f"Error: Invalid input: curve_fit_method='lm' requires number of observations >= number of parameters ({x_array.shape[0]} < {n_params})." # Wrap the model to ensure outputs are float64 def _model(x, *params): try: result = model_func(x, *params) return np.asarray(result, dtype=np.float64) except Exception as e: raise ValueError(f"Model evaluation error: {e}") try: curve_fit_kwargs = {'maxfev': 10000} if p0 is not None: curve_fit_kwargs['p0'] = p0 if bounds_t