4

I have a script that correctly plots 100 separate data files. Now I want to do a linear fit of each plot within a for loop. However, my script crashes when it gets to the fit command with the message "Skipping unreadable file "f(x) = a100*x + b%d". Can anyone help with the correct syntax? Thank you.

plotfile = "graph.eps"
set output plotfile
n=100
filename(n) = sprintf("%d_mod.int", n)
fstr(n) = sprintf('f(x) = a%d*x + b%d ' , n)
plot for [i = 1:n] filename(i) u 1:2 title sprintf("%d", i) w lp
fit for  [i = 1:n] fstr(i) filename(i) u 1:2 via a, b

1 Answer 1

5

fit doesn't support iterations. Here is how you can do it, but it needs some fiddling ;)

# define the functions depending on the current number
fstr(N) = sprintf("f%d(x) = a%d*x + b%d", N, N, N)

# The fitting string for a specific file and the related function
fitstr(N) = sprintf("fit f%d(x) 'file%d.dat' via a%d,b%d", N, N, N, N)

n = 2

# Do all the fits
do for [i=1:n] {
    eval(fstr(i))
    eval(fitstr(i))
}

# construct the complete plotting string
plotstr = "plot "
do for [i=1:n] {
    plotstr = plotstr . sprintf("f%d(x), 'file%d.dat'%s ", i, i, (i == n) ? "" : ", ")
}

eval(plotstr)

This works fine for me, if I use the following two test files:

File file1.dat:

1 1
2 2.1
3 3

and file2.dat:

1 1.5
2 2.7
3 4

The result with 4.6.5 is:

enter image description here

To have the actual result of the fitting displayed in the key you must construct the plotting string plotstr as follows:

plotstr = "plot "
do for [i=1:n] {
    t = sprintf("f%d(x) = %.2f*x + %.2f", i, value(sprintf('a%d', i)), value(sprintf('b%d', i)))
    plotstr = plotstr . sprintf("f%d(x) lt %d t '%s', ", i, i, t).\
                        sprintf(" 'file%d.dat' lt %d %s ", i, i, (i == n) ? "" : ", ")
}

with the result

enter image description here

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

6 Comments

This works perfectly for me (also using version 4.6.5). I just had to change to my file names -- exactly what I was looking for -- thank you very much!
Can I ask one more question? How can I change the plot string so that the entire fitting function f1(x) =a1*x + b1 is plotted instead of just f1(x)? If I extend the current expression to "f%d(x) = a%d*x + b%d" I get the error message "f_sprintf: attempt to print string value with numeric format"
f1(x) is the entire fitting function which is plotted. Or do you want to have f1(x) = a1*x + b1 placed in the legend (maybe even with a1 and b1 replaced with the actual numbers)?
Sorry for being inaccurate :( Yes, I meant how can I have the entire fitting function (with the actual numbers of a1 and b1) printed in the legend? I am still learning the syntax rules...
Your comment is incomplete. Beware, that do for ... { plot ... is different from plot for ..., see e.g. loop over array in gnuplot.
|

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.