2

This is similar to this question and this but my problem is that I have several hundred files that need to be simultaneously fitted and plotted on one graph. Unlike the other questions posted I'm looking for the best fits for each file, not for the global data set so cat won't work.

I was hoping to use fit.. for like I do for plot but it's not working so well. Here's what I've got so far:

f(x) = 1+d*exp(-(x-f)**2/(2*(g**2)))+a*exp((-(x-b)**2)/(2*(c**2)))

filename(n) = sprintf("rheosaxs_saxs_%005d_0001_var_rebin_div.dat", n)
fit f(x) for [n=575:584] filename(n) u 1:2 via a,b,c,d,f,g
plot for [n=575:584] filename(n) using 1:2, f(x)

the error I get is: line 60: undefined variable: for which corresponds to the fit f(x) for [n=a:b]

I know that my starting parameters are reasonable because I can plot them without the fit command and they look sensible. Similarly my plot for works ok.

Any ideas? Thank you :)

4
  • If your fit ... for would work, you would always overwrite the estimated fit parameters of the previous iteration. I posted a possible solution for such a szenario in stackoverflow.com/a/20323981/2604213, not sure if now there is a better approach using array, which were introduced with version 5.2. Commented Oct 25, 2017 at 12:36
  • I don't think that will work because for is defined differently in gnuplot to the standard definition Commented Oct 25, 2017 at 14:37
  • What do you refer to, that doesn't work? The answer I linked to, works as such. With arrays I mean something like do for [i = 1:10] { fit ... via a; array[i] = a; } I'll see later at home, if that could work. Commented Oct 25, 2017 at 15:28
  • ah ok, I think I understand :) I'll try Commented Oct 25, 2017 at 15:44

1 Answer 1

2

In version 5.2 gnuplot introduces arrays, which allow you to save the results of each fit and plot those later.

A simplified example script would be

file(n) = sprintf('myfile_%d.dat', n)
f(a, x) = a*x

array A[10]
do for [i=1:10] {
    tmpA = 1
    fit f(tmpA, x) file(i) via tmpA
    A[i] = tmpA
}

plot for [i=1:10] file(i),\
     for [i=1:10] f(A[i], x)

Although gnuplots arrays are implemented as linked list of user variables, it is not possible to use A[i] directly for the fit, but I had to use a temporary variable to get it right.

A full working example, including generation of random data, with python from gnuplot, uargh ;):

# generate some random data
system("python3 -c 'import random\nfor i in range(1, 11):\n\twith open(\"output_{0}.dat\".format(i), \"w\") as f:\n\t\tf.write(chr(10).join([str(i*100 + i* x * (1 + 0.1*(random.random()-0.5))) for x in range(0,100)]))'")


file(n) = sprintf('output_%d.dat', n)

f(a, b, x) = a*x + b
array A[10]
array B[10]
do for [i=1:10] {
    tmpA = 1
    tmpB = 1
    fit f(tmpA, tmpB, x) file(i) u 0:1 via tmpA, tmpB
    A[i] = tmpA
    B[i] = tmpB
}

plot for [i = 1:10] file(i) u 0:1 with points lt i notitle, \
     for [i=1:10] f(A[i], B[i], x) with lines lt i notitle

enter image description here

BTW: There is no fit for, because that is equivalent to do for { fit }. But when plotting, plot for generates a single plot with multiple functions, whereas do for { plot } makes several plots and should be used with multiplot

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.