How to define and access array in GNUplot?

24.9k views Asked by At

This is rather easy question or maybe too easy question. But i tried to find the way to done these already and could not find even in GNUplot document. Might be my mistake or misunderstood something about array concept in GNUplot. My question is How to define and access array in GNUplot?

Please just provide easy example of array declaration, assign value of array over loop. i think that's enough and i think this will be useful for other people too.

3

There are 3 answers

0
Karl On BEST ANSWER

(This answer will be obsolete with the next stable gnuplot release, as the 5.1 development tree now has native support for array variables.)

(The "splot" command in gnuplot uses the keyword "array" to define the size of NxM matrix that contains function values for a 3D plot. Nothing to do with array variables.)

Arrays like what a programmer knows from C, Pascal, Python, etc. do not exist in gnuplot today (gp5.0). They might get implemented one day, because they'd be highly useful to plot a family of curves with arbitrary (e.g. fitted) parameters.

If you are desperate about arrays in gnuplot, you can (ab)use the word() function (and other string functions) to achieve a somewhat limited substitute. It's also a bit cumbersome:

array = ""
f(a,x) = a*x
do for [i=1:5] {array = array.sprintf(" %.3f",i+rand(0)) }
print "array = ".array
set xr [0:]; set yr [0:30]
plot for [i=1:5] f(word(array,i),x) title word(array,i)." x"

This example writes a set of random numbers to a string variable named "array", and afterwards uses it to plot five linear functions that use the numbers in "array" for their slope. It's handy here that gnuplot autopromotes strings to numerics if used e.g. in an equation.

2
bmello On

If you are using Gnuplot 5.1 or superior and need a 1-d array, you simply define the array with size N, remembering that the indices go from 1 to N:

gnuplot> array A[3] #Array definition
gnuplot> A[1]=2
gnuplot> A[3]=4
gnuplot> print A[1]
2
gnuplot> print A    #Print the array, with empty A[2]
[2,,4]

If you need more than one dimension or are using previous versions of Gnuplot, you can do the following:

Since there are no vector variables in previous versions of Gnuplot, two functions can be defined to get and set values to a behind the scenes variable whose name include the index. The functions are:

aGet(name, i) = value(sprintf("_%s_%i", name, i)) 
aSet(name, i, value) = sprintf("_%s_%i = %.16e", name, i, value)

To assign and retrieve values on the array A you do

eval aSet("A",2,3)
print aGet("A",2)

What these functions do is to access a variable called _A_2.

You can build similar function to work with matrices:

mGet(name, i, j) = value(sprintf("_%s_%i_%i", name, i, j)) 
mSet(name, i, j, value) = sprintf("_%s_%i_%i = %.16e", name, i, j, value) 
0
Friedrich On

Inspired by @Karl 's answer, it looks even more like an array when putting the word function into another function:

array(n) = word("1 2 3 4 5 6 7 8 9", n)
print array(3)

This prints 3. So the indexing is one-based.

"Multiply" the array by 2:

print (b="", sum[i=1:9](b=b.(array(i)*2)." ", 0), b)

This prints 2 4 6 8 10 12 14 16 18. Here the sum function is (ab)used to loop over the array and its result is ignored.

And here is shorter, through less generic variant of @bmello's answer:

A_1=1.1; A_2=2.2; A_3=3.3
A(i) = value("A_".i)
print A(3)

For me it feels more intuitiv. The underscore _ can be seen simply as the set function. Also it is not limited to integer indices. Strings are also possible which give some dictionary-like behaviour.