7

Is there a way to plot a function based on values from a text file?

I know how to define a function in gnuplot and then plot it but that is not what I need. I have a table with constants for functions that are updated regularly. When this update happens I want to be able to run a script that draws a figure with this new curve. Since there are quite few figures to draw I want to automate the procedure.

Here is an example table with constants:

location a  b  c
1        1  3  4
2

There are two ways I see to solve the problem but I do not know if and how they can be implemented.

  1. I can then use awk to produce the string: f(x)=1(x)**2+3(x)+4, write it to a file and somehow make gnuplot read this new file and plot on a certain x range.
  2. or use awk inside gnuplot something like f(x) = awk /1/ {print "f(x)="$2 etc., or use awk directly in the plot command.

I any case, I'm stuck and have not found a solution to this problem online, do you have any suggestions?

mschilli
  • 1,884
  • 1
  • 26
  • 56
  • Why are you looking for a 1-line solution? – mgilson Feb 21 '13 at 17:31
  • When I use `gnuplot`, I always call it from inside of `Perl`. If this is not an option for whatever reason, I would recommend calling `awk` from inside of your `gnuplot` script. See [here](http://stackoverflow.com/questions/12846717/using-awk-or-other-shell-command-inside-gnuplot-function) and [here](http://security.riit.tsinghua.edu.cn/~bhyang/ref/gnuplot/datafile3-e.html) for ways to accomplish this. – Steve Feb 21 '13 at 23:49
  • I think the description of the problem is not very precise, specifically how the sample text file is going to interpreted. – U. Windl Jun 05 '20 at 06:00

4 Answers4

3

Another possibilty to have a somewhat generic version for this, you can do the following:

Assume, the parameters are stored in a file parameters.dat with the first line containing the variable names and all others the parameter sets, like

location a b c
1        1 3 4

The script file looks like this:

file = 'parameters.dat'
par_names = system('head -1 '.file)
par_cnt = words(par_names)

# which parameter set to choose
par_line_num = 2
# select the respective string
par_line = system(sprintf('head -%d ', par_line_num).file.' | tail -1')
par_string = ''
do for [i=1:par_cnt] {
  eval(word(par_names, i).' = '.word(par_line, i))
}
f(x) = a*x**2 + b*x + c

plot f(x) title sprintf('location = %d', location)
Christoph
  • 47,569
  • 8
  • 87
  • 187
1

This question (gnuplot store one number from data file into variable) had some hints for me in the first answer.

In my case I have a file which contains parameters for a parabola. I have saved the parameters in gnuplot variables. Then I plot the function containing the parameter variables for each timestep.

#!/usr/bin/gnuplot

datafile = "parabola.txt"

set terminal pngcairo size 1000,500
set xrange [-100:100]
set yrange [-100:100]
titletext(timepar, apar, cpar) = sprintf("In timestep %d we have parameter a = %f, parameter c = %f", timepar, apar, cpar)

do for [step=1:400] {
  set output sprintf("parabola%04d.png", step)

  # read parameters from file, where the first line is the header, thus the +1
  a=system("awk '{ if (NR == " . step . "+1) printf \"%f\", $1}' " . datafile)
  c=system("awk '{ if (NR == " . step . "+1) printf \"%f\", $2}' " . datafile)

  # convert parameters to numeric format
  a=a+0.
  c=c+0.

  set title titletext(step, a, c)

  plot   c+a*x**2
}

This gives a series of png files called parabola0001.png, parabola0002.png, parabola0003.png, …, each showing a parabola with the parameters read from the file called parabola.txt. The title contains the parameters of the given time step.

For understanding the gnuplot system() function you have to know that:

  • stuff inside double quotes is not parsed by gnuplot
  • the dot is for concatenating strings in gnuplot
  • the double quotes for the awk printf command have to be escaped, to hide them from gnuplot parser

To test this gnuplot script, save it into a file with an arbitrary name, e.g. parabolaplot.gplot and make it executable (chmad a+x parabolaplot.gplot). The parabola.txt file can be created with

awk 'BEGIN {for (i=1; i<=1000; i++) printf "%f\t%f\n", i/200, i/100}' > parabola.txt

Community
  • 1
  • 1
erik
  • 2,278
  • 1
  • 23
  • 30
0
awk '/1/ {print "plot "$2"*x**2+"$3"*x+"$4}' | gnuplot -persist

Will select the line and plot it

parkydr
  • 7,596
  • 3
  • 32
  • 42
0

This was/is another question about how to extract specific values into variables with gnuplot (maybe it would be worth to create a Wiki entry about this topic). There is no need for using awk, you can do this simply with gnuplot only (hence platform-independent), even with gnuplot 4.6.0 (March 2012). You can do a stats (check help stats) and assign the values to variables.

Data: SO15007620_Parameters.txt

location a  b  c
1        1  3  4
2       -1  2  3
3        2  1 -1

Script: (works with gnuplot 4.6.0, March 2012)

### read parameters from separate file into variables
reset

FILE = "SO15007620_Parameters.txt"

myLine = 1     # line index 0-based
stats FILE u (a=$2, b=$3, c=$4) every ::myLine::myLine nooutput

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

plot f(x) w l lc rgb "red" ti sprintf("f(x) = %gx^2 + %gx + %g", a,b,c)
### end of script

Result:

enter image description here

theozh
  • 22,244
  • 5
  • 28
  • 72