I'm quite new to Mathematica. I've used Matlab in the past but it was a long time ago.

I'm working on developing a Dark Room Light meter and need to fit some curves. But, ideally, I need to fit all the curves in a single 2 variable surface.

I couldn't upload the picture, so I leave a link to it: Plot Each curve corresponds to a Printing Range that would be the -y- axis, while the exposure would be the -x- axis and the Density (darkness of the print) will be the -z- axis. The variables of the function will be x and y and the result should be the Density.

One approach would be taking individual values of each curve at different points and try to fit a 2 variable function. But since I see that it's quite easy to fit a function for each curve, I would like to approach the two variable function from the curve fitting of each plot.

Separating each plot is not an issue since I can even do it in Photoshop before feeding it to Mathematica.

Thanks in advance for you help.

  • $\begingroup$ Do you have the data you want to fit (ie, a list of data points)? Please post any Mathematica code or data you have -- it makes it a lot easier for people to help you. And have you looked at NonlinearModelFit? $\endgroup$ Oct 9, 2017 at 9:48
  • $\begingroup$ I have plots from paper manufacturers, not data points. I've posted a picture of the plots given by one manufacturer. For the moment, I don't have any code to post, sorry. It's in a link since I could not upload the file directly. I almost know how to fit each separate curve, but I don't know how to fit them all on a surface. $\endgroup$ Oct 9, 2017 at 10:18
  • $\begingroup$ In the context of computer graphics, this operation is called "lofting" or "skinning". $\endgroup$ Mar 25, 2018 at 17:36

2 Answers 2


I suppose that you can import the data points of each curve into Mathematica somehow, so that you obtain a matrix curves such as I tried to emulated below.

tlist = Table[t, {t, 0, 5., 0.1}];
nlist = Range[5];
curves = Table[ Map[t \[Function] {t, 1/Exp[1 + Exp[-n (t - (1 + 1/n))]]}, tlist], {n, nlist}];
ListLinePlot[curves, PlotLegends -> nlist,  AxesLabel -> {"LogE", "Density"}]

enter image description here

Here, nlist is a list of parameters; each entry corresponds to one entry in curves. I create 3-dimensional data by merging nlist and curves as follows; afterwards I use Interpolation to do, well, the interpolation.

data = Join[
   Table[ConstantArray[{N[n]}, Length[tlist]], {n, nlist}],
f = Interpolation[Flatten[data, 1]];

Now, we can plot that as a surface. I also show how the 2-d curves are embedded into $\mathbb{R}^3$. I hope this helps.

 Plot3D[f[n, t], {n, 1, 5}, {t, Min[tlist], Max[tlist]}, 
  AxesLabel -> {"n", "LogE"}],
 Graphics3D[{Thick, Line[data]}]

enter image description here

  • $\begingroup$ Thank you very much, Henrik! That's almost what I need. The only missing thing is how to get a 2 variable function that represents this surface. $\endgroup$ Oct 9, 2017 at 15:18
  • $\begingroup$ You're welcome. The function f constructed above should be what you are looking for. All the data is packed into an InterpolationFunction object and hidden from the user. You can use f as any other pure function; e.g., you can also evaluate derivatives of it. See the documentation of Interpolation for more details. You can also find various options for the interpolation, there. $\endgroup$ Oct 9, 2017 at 15:32
  • $\begingroup$ Thank you very much again for your response. I almost understand what I need to do. The only problem with this approach is that I cannot get the expression of the InterpolatingFunction and I need to get it in order to include it in my C# code. I cannot use Mathematica API since it's running on a Raspberry Pi and I want to keep it as simple as possible. $\endgroup$ Oct 10, 2017 at 8:39
  • $\begingroup$ Ah, I see. Maybe these will help: mathematica.stackexchange.com/questions/59944 or mathematica.stackexchange.com/questions/105459 $\endgroup$ Oct 10, 2017 at 9:45
  • $\begingroup$ Thank you very much, Henrik. You have helped me a lot. I'm now on the way to get a proper function. I really, really, appreciate your help. $\endgroup$ Oct 10, 2017 at 10:34


Since you did not supply the curves to fit, we firstly generate several curves:

curves1 = Table[{2 i, 2 j, Sin[2 i + 2 j]}, {i, 0, 2}, {j, 0, 6, 0.5}];
curves2 = Table[{2 i + 1, 2 j + 1, Sin[2 i + 2 j + 2]}, {i, 0, 2}, {j, 0, 6, 0.5}];
Graphics3D[{Red, Thick, Line[curves1], Blue, Line[curves2]}, Boxed -> False]

enter image description here


If you just want to visualize a surface to fit all these curves, BSplineSurface is enough:

bsSurface = BSplineSurface[Flatten[{curves1, curves2}, 1]];
Graphics3D[{Red, Thick, Line[curves1], Blue, Thick, Line[curves2],
    Opacity[0.6], Gray, EdgeForm[], bsSurface}, Boxed -> False]

enter image description here

However if you want to interpolate the data of all the curves, i.e. curves1 and curves2, Interpolation works for such purpose. Interpolation can fit multidimensional functions:

interpolateFunciton = Interpolation[{{#1, #2}, #3} & @@@ Flatten[{curves1, curves2}, 2]];


Validate our interpolateFunciton at the point with coordinate {3.5, 3.5, ?}, which does not belong to either curves1 or curves2:

pt = {#1, #2, interpolateFunciton[#1, #2]} & @@ {3.5, 3.5};
Graphics3D[{Red, Thick, Line[curves1], Blue, Thick, Line[curves2], 
    Opacity[0.6], Gray, EdgeForm[], bsSurface, PointSize[.02], 
    Black, Point[pt]}, Boxed -> False]

enter image description here

En, the black point almost lies within the interpolated surface.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.