2

Say I have the following file:

1,2,3
4,5,6
7,8,9

I would like to have gnuplot plot 3 polynomials of the form ax^2 + bx +c, using the file values as coefficients. Performing this directly, I would do:

plot x**2+2*x+3, 4*x**2+5*x+6, 7*x**2+8*x+9

But I would like to do this programatically, for an arbitrary number of lines in the input file.

I think I might be close with code inspired by this answer:

n= "`awk 'END {print NR}' < test.dat`"
i=0
while i<n{
f(a,b,c,x)=a*x**2+b*x+c
plot 'test.dat' every ::i::i using f($1,$2,$3,x)
}

But this fails with undefined variable: x

Community
  • 1
  • 1
jake
  • 361
  • 1
  • 14
  • With the syntax `plot 'test.dat' ...` you plot a data file, and not a function of x. So the variable x isn't defined. You could also have a look at [Plotting a function directly from a text file](http://stackoverflow.com/q/15007620/2604213). In any case, there isn't a straightforward solution. – Christoph Oct 31 '14 at 19:50

3 Answers3

0

I've had the same problem for ages and finally I managed to find a solution. It requires a creative use of the stats function to assign the values from the file to the variables and a couple of do for [...] loops to store some commands in a temp file

filename = "InputFileName.dat"
stats filename nooutput
nlines = STATS_records-1
set print "temp.gnuplot"
do for [i=0:nlines] {\
  print sprintf("stats filename every ::%i::%i using (a%i=$1,b%i=$2,c%i=$3,0):(0) nooutput",i,i,i,i,i)}
set print
load "temp.gnuplot"
set print "temp.gnuplot"
do for [i=1:nlines] {print sprintf("replot  a%i*x**2 + b%i*x + c%i",i,i,i)}
plot a0*x**2 + b0*x +c0
load "temp.gnuplot"
set print

Change the filename variable as you need. You can remove the temp file once you are finished with a system call like this ! rm temp.gnuplot.

I know is not particularly elegant and I especially don't like the use of a temp file, if somebody knows how to execute a string variable I'd be happy to know. But hey, it works (even under Windows)!

Edit: forgot to credit thse for the input.

0

It's an old thread but thanks to the previous answer, I can propose an upgraded version using strings instead of a temp file. That one, there is no need to bother deleting the useless temp file afterwards.

filename = "InputFileName.dat"
stats filename nooutput

nlines = STATS_records-1

paramstr(N) = sprintf("stats filename every ::%i::%i using (a%i=$1,b%i=$2,c%i=$3,0):(0) nooutput",N,N,N,N,N)
do for [i=0:nlines] {
    eval(paramstr(i))
}

plotstr = "p "
do for [i=0:nlines] {
    plotstr = plotstr . sprintf("a%i*x**2 + b%i*x + c%i%s",i,i,i,(i == nlines) ? "" : ", ")
}

eval(plotstr)

Maybe that some set xrange and set yrange tuning will be necessary to look at what you are interested in though.

afagot
  • 1
0

This question is similar to Plotting a function directly from a text file, however, with more parameters and in several lines. At the time of OP's question there were no arrays in gnuplot, but you can simply store your values in a string and address them via some functions using word() and real(), check help word and help real).

There is no need for awk (as in the link), no temporary files (solution of @Joseph D'Arimathea) and no extra loops or eval() (solution of @afagot).

Data: SO26680694.dat

1,2,3
4,5,6
7,8,9

Script: (works with gnuplot 4.6.0, March 2012)

### extract multiple parameters from a datafile
reset

FILE = "SO26680694.dat"

set datafile separator ','
myParams = ''
stats FILE u (myParams = myParams.sprintf(' %g %g %g', $1, $2, $3),0) nooutput

myParam(s,i) = real(word(myParams,(s-1)*3+i))
a(s) = myParam(s,1)
b(s) = myParam(s,2)
c(s) = myParam(s,3)

f(x,a,b,c) = a*x**2 + b*x + c

plot for [i=1:3] f(x,a(i),b(i),c(i)) title sprintf("%gx^2 + %gx + %g",a(i),b(i),c(i))
### end of script

Result:

enter image description here

theozh
  • 22,244
  • 5
  • 28
  • 72