title: Generation of free running list of lapse rate and guess rate for psychometric curve fitting (Scipy)
body: <p>As a new user to the curve fitting function from scipy and a relatively new user of python, I am a little confused as to what *popt and p0 exactly generates (with reference to <a href="http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html" rel="nofollow">this</a>)</p>
  
  <p>So I am trying to plot a psychometric fitting here based of a customized sigmoid function formula that accounts for a guess and lapse rate (Both with values between 0 and 1 to account for participant guessing and performance lapse rates in an experiment. These values would define the fit on the lower and upper end of the curve fit respectively.)</p>
  
  <p>I can get the function to generate the best lapse rate it could fit to the curve when a fixed guess rate was set outside the function. But when I want the function to generate both the best lapse rate and guess rate, it couldn't, and gave the following error:-</p>
  
  <blockquote>
    <p>File "C:\Users\Aaron\Anaconda2\lib\site-packages\scipy\optimize\minpack.py", line 447, in _general_function
        return function(xdata, <em>params) - ydata
    TypeError: sigmoidscaled() takes exactly 5 arguments (4 given)</em></p>
  </blockquote>
  
  <p>Now I am aware that this means that there was no value coming from the 'guess rate' variable and thus this error. So how is it that the function was able to generate a 'lapse rate' but not a 'guess rate' here?</p>
  
  <p>These are the codes when the guess rate is a prefixed value and the curve fit is successful:-</p>
  
  <pre><code>import numpy as np
  import pylab
  from scipy.optimize import curve_fit
  from matplotlib.pyplot import *
  
  n = 20 #20 trials
  ydata = [0/n, 9.0/n, 9.0/n, 14.0/n, 17.0/n] #Divided by n to fit to a plot of y =1
  xdata = np.array([ 1.0, 2.0, 3.0, 4.0, 5.0])
  
  guess = 0.05 #Set the minimum chance level
  
  #The scaled sigmoid function
  def sigmoidscaled(x, x0, k, lapse):
      F = (1 + np.exp(-k*(x-x0))) 
      z = guess + (1-guess-lapse)/F
      return z
  
  p0=[1,1,-10] 
  popt, pcov = curve_fit(sigmoidscaled, xdata, ydata, p0, maxfev = 3000)
  
  #Start and End of x-axis, in spaces of n. The higher the n, the smoother the curve.
  x = np.linspace(1,5,20)
  #The sigmoid values along the y-axis, generated in relation to the x values and the 50% point.
  y = sigmoidscaled(x, *popt)
  
  pylab.plot(xdata, ydata, 'o', label='Psychometric Raw', color = 'blue')
  pylab.plot(x,y, label='Psychometric Fit', color = 'blue')
  #y axis range.
  pylab.ylim(0, 1)
  #Replace x-axis numbers as labels and y-axis numbers as percentage
  xticks([1., 2., 3., 4., 5.], ['C1','CN2','N3','CN4','S5'])
  yticks([0.0, 0.2, 0.4, 0.6, 0.8, 1.0], ['0%','20%','40%','60%','80%','100%'])
  pylab.legend(loc='best')
  xlabel('Conditions')
  ylabel('% perceived more sin like')
  pylab.show()
  </code></pre>
  
  <p>Whereas when I tried to have the formula try to find the best 'guess' value, it couldn't. (Here, 'guess = 0.05 #Set the minimum chance level' was removed and a guess variable inserted into the sigmoid function.) :-</p>
  
  <pre><code>import pylab
  from scipy.optimize import curve_fit
  from matplotlib.pyplot import *
  
  n = 20 #20 trials
  ydata = [0/n, 9.0/n, 9.0/n, 14.0/n, 17.0/n] #Divided by n to fit to a plot of y =1
  xdata = np.array([ 1.0, 2.0, 3.0, 4.0, 5.0])
  
  
  #The scaled sigmoid function
  def sigmoidscaled(x, x0, k, lapse, guess):
      F = (1 + np.exp(-k*(x-x0))) 
      z = guess + (1-guess-lapse)/F
      return z
  
  p0=[1,1,-10] 
  popt, pcov = curve_fit(sigmoidscaled, xdata, ydata, p0, maxfev = 3000)
  
  #Start and End of x-axis, in spaces of n. The higher the n, the smoother the curve.
  x = np.linspace(1,5,20)
  #The sigmoid values along the y-axis, generated in relation to the x values and the 50% point.
  y = sigmoidscaled(x, *popt)
  
  pylab.plot(xdata, ydata, 'o', label='Psychometric Raw', color = 'blue')
  pylab.plot(x,y, label='Psychometric Fit', color = 'blue')
  #y axis range.
  pylab.ylim(0, 1)
  #Replace x-axis numbers as labels and y-axis numbers as percentage
  xticks([1., 2., 3., 4., 5.], ['C1','CN2','N3','CN4','S5'])
  yticks([0.0, 0.2, 0.4, 0.6, 0.8, 1.0], ['0%','20%','40%','60%','80%','100%'])
  pylab.legend(loc='best')
  xlabel('Conditions')
  ylabel('% perceived more sin like')
  pylab.show() 
  </code></pre>