Is there a way to load data from a file into a Gnuplot array? I am working with a program that provides the data and calls gnuplot internally to create a plot. Now I am trying to set the xrange that the upper limit is set where the data in the second column finally approaches zero. I have googled a lot and tried different methods. Unfortunately without success. The most promising but still not working approach seems to me to import the data and store it in an array. An excerpt from the code is provied below:
stats '<datafile>' using 1:($2/1000.) nooutput
array myarray[STATS_records]
do for [i=STATS_records:0:-1] {
stats '<datafile>' using 1:($2/1000.) index i nooutput
myarray[i] = STATS_min_y
}
The stats expression in the loop causes an error because no values are found. Thank you in advance for your suggestions or alternative solutions.
From your current question title and code snippet I assume you want to read data reversed into an array.
Now I am trying to set the xrange that the upper limit is set where the data in the second column finally approaches zero.
This sentence makes me think that maybe there is more behind which you don't show and which can maybe solved also without arrays. Maybe we are running into a xy-problem?
The following script reads a column of a data file reversed into an array.
Data: SO76218289.dat
1 1.0
2 2.1
3 3.2
4 4.3
5 5.4
6 6.5
7 7.6
8 8.7
9 9.8
10 10.9
Script: (requires gnuplot>=5.2.0)
### read data from file reversed into array
reset session
FILE = "SO76218289.dat"
stats FILE u 0 nooutput # get number of rows
rowCount = STATS_records
array A[rowCount] # set array size
stats FILE u (A[int(rowCount-$0)] = $2) nooutput
print A
### end of script
Result:
[10.9,9.8,8.7,7.6,6.5,5.4,4.3,3.2,2.1,1.0]
Addition:
Actually, it was a bit of a xy-problem: You asked for putting data into an array, but the actual goal was to limit the xrange to the range where y>0
. This can be done simpler. Using the ternary operator (check help ternary
) the x-values will be set to NaN
if y<0
. A value of NaN
will not be plotted and considered for the x-autorange. Hence, in the example below the x-range is automatically limited to [3:7]
. If the y-values might get below zero within the limited range and you nevertheless want lines drawn down to zero, the script needs to be adapted.
Script:
### limit xrange to data y>0
reset session
$Data <<EOD
1 -1.0
2 -0.5
3 0.5
4 3.0
5 2.0
6 1.0
7 0.5
8 -0.1
9 -0.5
10 -1.0
EOD
plot $Data u ($2>0 ? $1 : NaN):2 w lp pt 7 lc "red" notitle
### end of script
Result:
Addition 2:
Just to illustrate, you can also limit the data to an x-range where y>0
and including the first sequence of N
values y<=0
. This requires stats
and a more difficult statement to understand using ternary operators and serial evaluation (check help operators binary
). The final limitation will be done by every
(check help every
).
Script:
### limit x-range to values with y>0 and N values y<=0
reset session
$Data <<EOD
1 -1.0
2 -0.5
3 0.5
4 3.0
5 2.0
6 1.0
7 0.5
8 0.0
9 0.0
10 0.0
11 -1.0
12 -2.0
EOD
N = 3 # max. number of y-values <0 in a sequence
n0 = n1 = NaN
c = 0
stats $Data u ($2>0 && n0!=n0 ? n0=$0 : $2<=0 && n0==n0 && n1!=n1 ? c=c+1 : c=0, c==N ? n1=$0 : 0) nooutput
print n0,n1
plot $Data u 1:2 every ::n0::n1 w lp pt 7 lc "red"
### end of script
Some explanations:
n0
and n1
are initialized to NaN
and c=0
.What is the meaning of:
($2>0 && n0!=n0 ? n0=$0 : $2<=0 && n0==n0 && n1!=n1 ? c=c+1 : c=0, c==N ? n1=$0 : 0)
y>0
and n0
is NaN
(see gnuplot: How to compare to NaN?) then set n0
to the current line index $0
which will be the first time y>0
.y<=0
and n0
is not NaN
and n1
is NaN
, increase the counter c
by 1, else reset the counter to c=0
.c
is equal to N
set n1
to the current line index $0
.In summary: n0
contains the line index with the first time y>0
and n1
contains the line index when y
was N
-times <=0
(but only after n0
was set to some value).
When you plot the data, you simply limit it via every ::n0::n1
.
The example will limit the x-range to [3:10] because the last N=3 y-values are y<=0.
Result: