4
votes

I'm quite new with gnuplot and so maybe my question has an obvious answer. Please excuse if this is too noobish.

I have the following data

20 500 1.0
30 500 0.95
40 500 0.85
50 500 0.7
60 500 0.5

20 1000 1.1
30 1000 1.05
40 1000 0.95
50 1000 0.8
60 1000 0.6

20 1500 1.2
30 1500 1.15
40 1500 1.05
50 1500 0.9
60 1500 0.7

20 2000 1.26
30 2000 1.22
40 2000 1.13
50 2000 0.99
60 2000 0.79

20 2500 1.33
30 2500 1.29
40 2500 1.21
50 2500 1.06
60 2500 0.88

Plotting this as a surface worked fine. Now I would like to plot this as 5 separate lines (using 1:3) and have the 2nd column as 'title at end' for each of the lines.

I tried

plot "demo.dat" using 1:3:2 with lines title columnhead(2) at end

but this will only label the last line (which is bogus) with 500 and ignore all the others. Also it sets 500 as title in the key box (which I would like to set to another string). Is that possible or do I have to split the blocks into several files as suggested in How to plot single/multiple lines depending on values in a column with GNUPlot ?

2

2 Answers

1
votes

You may try in two steps:

 plot 'demo.dat' u 1:3 notitle with lines, \
  'demo.dat' u 1:3:2 every ::4::4 notitle with labels
  • first plotting the data.

  • then adding a label at the last point of each block (composed of 5 points going from 0 to 4), or at the point before the last one replacing ::4::4 by ::3::3.

1
votes

Another rather general solution. No need to split the data into several files. Of course, it would be easier if the data was split into subblocks by two empty lines, however, the OP's data is separated only by single empty lines. How to handle this without modifying the data outside gnuplot?

For the following solution you don't have to know in advance how many subblocks your data has and how many datapoints there are in one subblock, because after the first plot the variable c contains the number of datapoints (here 25) divided by the number of subblocks (here 5) reduced by 1, which is the index (here 4) of the last datapoint in a subblock. Assumption: each subblock has the same number of datapoints.

Furthermore:

  • different colors for the subblocks
  • value of column 2 as label at the end
  • some other text in the in the legend/key

This works even with gnuplot 4.6 if you replace reset session with reset and remove the datablock $Data <<EOD ... EOD and in the plot command replace $Data with your filename, e.g. 'myFile.dat'.

Code:

### plotting some subblock data
reset session

$Data <<EOD
20 500 1.0
30 500 0.95
40 500 0.85
50 500 0.7
60 500 0.5

20 1000 1.1
30 1000 1.05
40 1000 0.95
50 1000 0.8
60 1000 0.6

20 1500 1.2
30 1500 1.15
40 1500 1.05
50 1500 0.9
60 1500 0.7

20 2000 1.26
30 2000 1.22
40 2000 1.13
50 2000 0.99
60 2000 0.79

20 2500 1.33
30 2500 1.29
40 2500 1.21
50 2500 1.06
60 2500 0.88
EOD

set rmargin 7
set key at graph 0.95, 0.95 reverse

plot $Data u 1:3:(c=int(($0+1)/(column(-1)+1))-1,column(-1)) w lp pt 7 lc var notitle, \
     ''    u 1:3:2 every ::c::c w labels offset 3,0 \
           title "This is some other text\nfor the legend"
### end of code

Result:

enter image description here

Addition:

Here is another version which allows variable subblock sizes. Nevertheless, the label will be placed at the last datapoint of the subblock. The simple "trick" is to reverse the dataset and put the label at the first datapoint of each subblock via every ::0:0:0:0. Furthermore, a single empty line will be replaced by double empty line and hence the subblocks can be addressed by index. For illustration, the original data is slightly modified.

In order to reverse a dataset it needs to be in a datablock (see gnuplot: load datafile 1:1 into datablock)

Code: (requires gnuplot >=5.2)

### plot subblocks variable in length separated by only one empty line
# and put labels at *last* values
# requires gnuplot >=5.2
reset session

$Data <<EOD
10 500 1.05
20 500 1.0
30 500 0.95
40 500 0.85
50 500 0.7
60 500 0.5

20 1000 1.1
30 1000 1.05
40 1000 0.95
50 1000 0.8

20 1500 1.2
30 1500 1.15
40 1500 1.05
50 1500 0.9
60 1500 0.7
70 1500 0.51
80 1500 0.30

20 2000 1.26
30 2000 1.22
40 2000 1.13
50 2000 0.99
60 2000 0.79
70 2500 0.61

20 2500 1.33
30 2500 1.29
40 2500 1.21
50 2500 1.06
60 2500 0.88
EOD

# reverse data
set print $DataReversed
    do for [i=|$Data|:1:-1] { 
        if (strlen($Data[i])==1) {print ""}
        print $Data[i]
    }
set print
print $DataReversed

set rmargin 7
set yrange [0.2:]

plot $DataReversed u 1:3:(LastIdx=column(-2),$2) every ::0:0:0:0 w labels offset 3,0 notitle, \
     for [i=0:LastIdx] '' u 1:3 index LastIdx-i w lp pt 7 lc i ti sprintf("Subblock %d",i)
### end of code

Result:

enter image description here