2

I have a file "a_test.dat" with two data blocks that I can select via the corresponding index.

# first
x1  y1
3   1
6   2
9   8

# second
x2  y2
4   5
8   2
2   7

Now I want to connect the data points of both indices with an arrow.

set arrow from (x1,y1) to (x2,y2).

I can plot both blocks with one plot statement. But I cannot get the points to set the arrows.

plot "a_test.dat" index "first" u 1:2, "" index "second" u 1:2

magfan
  • 181
  • 1
  • 9
  • Do you have _one_ or _two_ blank lines as separation? If you want to address (sub)blocks via `index` the separation should be *two* empty lines. So, as I understand you want to draw an arrow from 3,1 to 4,5 and from 6,2, to 8,2, etc., correct? – theozh Feb 18 '23 at 18:20

2 Answers2

1

From version 5.2 you can use gnuplot arrays:

stats "a_test.dat" nooutput
array xx[STATS_records]
array yy[STATS_records]
# save all data into two arrays
i = 1
fnset(x,y) = (xx[i]=x, yy[i]=y, i=i+1)
# parse data ignoring output
set table $dummy
plot "" using (fnset($1,$2)) with table
unset table
# x2,y2 data starts at midpoint in array
numi = int((i-1)/2)

plot for [i=1:numi] $dummy using (xx[i]):(yy[i]):(xx[numi+i]-xx[i]):(yy[numi+i]-yy[i]) with vectors

Use stats to count the number of lines in the file, so that the array can be large enough. Create an array xx and another yy to hold the data. Use plot ... with table to read the file again, calling your function fnset() for each data line with the x and y column values. The function saves them at the current index i, which it increments. It was initialised to 1.

For 3+3 data lines, i ends up at 7, so we set numi to (i-1)/2 i.e. 3. Use plot for ... vectors to draw the arrows. Each arrow needs 4 data items from the array. Note that the second x,y must be a relative delta, not an absolute position.

enter image description here

meuh
  • 11,500
  • 2
  • 29
  • 45
1

Another solution with gnuplot only. Of course, you could also use external tools to modify your data, but if possible, I prefer gnuplot-only solutions, since they are platform-independent. It is basically the same principle like here.

The following script works independent if your subdatablocks are separated by one or two empty lines.

Data: SO75483386.dat

# first
x1  y1
3   1
6   2
9   8

# second
x2  y2
4   5
8   2
2   7

Script: (requires gnuplot>=5.2.0, because of indexing of datablocks)

### combine lines of different subblocks into one line
reset session

FILE = "SO75483386.dat"

set table $Temp
    plot FILE u 1:2 w table
unset table

set print $Data
    N = |$Temp|/2
    do for [i=1:N] { 
        print $Temp[i]."   ".$Temp[i+N]
    }
unset print
print $Data

set offsets 1,1,1,1

plot $Data u 1:2:($3-$1):($4-$2):0 w vec lc var lw 2 notitle
### end of script

Result:

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

enter image description here

theozh
  • 22,244
  • 5
  • 28
  • 72