title: Curve fitting multiple outputs from a single function with scipy
body: <p>OK, I have a function which uses a range of parameters to calculate the effect on two separate variables over time. These variables have already been curve-matched to some existing data to minimize the variation (shown below)
  <a href="https://i.stack.imgur.com/KgMnX.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/KgMnX.png" alt="example"></a></p>
  
  <p>I want to be able to check the previous working, and match new data. I have been trying to use the <code>scipy.optimize.curve_fit</code> function, by stacking the x and y data resulting from my function (as suggested here: <a href="https://stackoverflow.com/questions/26242979/fit-multiple-parametric-curves-with-scipy">fit multiple parametric curves with scipy</a>). </p>
  
  <p>It may not be the right method, or I may just be misunderstanding, but my code keeps running into a type error <code>TypeError: Improper input: N=3 must not exceed M=2</code></p>
  
  <p>My simplified prototype code was initially taken from here: <a href="https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html" rel="nofollow noreferrer">https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html</a></p>
  
  <pre><code>import numpy as np
  import matplotlib.pyplot as plt
  from scipy.optimize import curve_fit
  
  def func(x, a, b, c):
      result = ([],[])
      for i in x:
          #set up 2 example curves
          result[0].append(a * np.exp(-b * i) + c)
          result[1].append(a * np.exp(-b * i) + c**2)
      return result #as a tuple containing 2 lists
  
  #Define the data to be fit with some noise:
  xdata = list(np.arange(0, 10, 1))
  y = func(xdata, 2.5, 5, 0.5)[0]
  y2 = func(xdata, 1, 1, 2)[1]
  
  #Add some noise
  y_noise = 0.1 * np.random.normal(size=len(xdata))
  y2_noise = 0.1 * np.random.normal(size=len(xdata))
  
  ydata=[]
  ydata2=[]
  
  for i in range(len(y)): #clunky
      ydata.append(y[i] + y_noise[i])
      ydata2.append(y2[i] + y2_noise[i])
  
  plt.scatter(xdata, ydata, label='data')
  plt.scatter(xdata, ydata2, label='data2')
  #plt.plot(xdata, y, 'k-', label='data (original function)')
  #plt.plot(xdata, y2, 'k-', label='data2 (original function)')
  
  #stack the data
  xdat = xdata+xdata
  ydat = ydata+ydata2
  
  popt, pcov = curve_fit(func, xdat, ydat)
  
  plt.plot(xdata, func(xdata, *popt), 'r-',
           label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))
  
  plt.xlabel('x')
  plt.ylabel('y')
  plt.legend()
  plt.show()
  </code></pre>
  
  <p>Any help much appreciated !</p>