Scipy.optimize - curve fitting with fixed parameters

Using scipy, there are no builtin options that I am aware of. You will always have to do a work-around like the one you already did.

If you are willing to use a wrapper package however, may I recommend my own symfit? This is a wrapper to scipy with readability and less boilerplate code as its core principles. In symfit, your problem would be solved as:

from symfit import parameters, variables, exp, Fit, Parameter

a, b, c, d = parameters('a, b, c, d')
x, y = variables('x, y')

model_dict = {y: a * exp(-(x - b)**2 / (2 * c**2)) + d}

fit = Fit(model_dict, x=xdata, y=ydata)
fit_result = fit.execute()

The line a, b, c, d = parameters('a, b, c, d') makes four Parameter objects. To fix e.g. the parameter c to its initial value, do the following anywhere before calling fit.execute():

c.value = 4.0
c.fixed = True

So a possible end result might be:

from symfit import parameters, variables, exp, Fit, Parameter

a, b, c, d = parameters('a, b, c, d')
x, y = variables('x, y')

c.value = 4.0
c.fixed = True

model_dict = {y: a * exp(-(x - b)**2 / (2 * c**2)) + d}

fit = Fit(model_dict, x=xdata, y=ydata)
fit_result = fit.execute()

If you want to be more dynamic in your code, you could make the Parameter objects straight away using:

c = Parameter(4.0, fixed=True)

For more info, check the docs: http://symfit.readthedocs.io/en/latest/tutorial.html#simple-example

The above example using symfit would surely simply the syntax of the fitting approach, however, does the example given really constrain the variable c?

If you look at the fit_result.param you get the following:

OrderedDict([('a', 16.374368575343127), ('b', 0.49201249437123556), ('c', 0.5337962977235504), ('d', -9.55593614465743)])

The parameter c is not 4.0.