Search code examples
gnuplotmissing-data

How to paste gnuplot datablocks?


I have to calculate new values within a for loop in gnuplot. How can I paste the results from $Data? I am getting the error message "data block name must be followed by << EODmarker".

do for [selected_label in LABELS] {
    set table $Data  
    plot '' index group using ( @sel ):( @corrected_volume ) with table
    unset table
    
    $Temp = $Temp . $Data        
}

print $Temp

Solution

  • Check help table. You can append to a datablock.

    I don't know the details and the dependencies of your script, but check the example below. Hope it helps. By the way, you could also use

    set print $Temp append
        print "something"
    set print
    

    Script:

    ### append to an existing datablock
    reset session
    
    $Temp <<EOD
     1   4
     2   5
     3   6
    EOD
    
    set table $Temp append
        do for [i=1:3] {
            set samples 3
            set xrange [0:2]
            plot '+' u ($1*i):(($1*i)**2) w table
        }
    unset table
    print $Temp
    
    ### end of script
    

    Result:

     1   4
     2   5
     3   6
     0       0
     1       1
     2       4
     0       0
     2       4
     4       16
     0       0
     3       9
     6       36
    

    Addition:

    You can mimic Linux' paste command in gnuplot-only. You index the lines of the datablock (index is 1-based) and remove the last character (which is newline \n) and concatenate it with another string and print it to a new datablock. You need to make sure you add not more lines than the original datablock has.

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

    ### mimic Linux' paste with gnuplot only
    reset session
    
    $Temp <<EOD
     1   4
     2   5
     3   6
    EOD
    
    set print $Temp2
        do for [j=0:2] {
            tmp_line = ''
            do for [i=1:3] {
                tmp_line = tmp_line.sprintf("  %g  %g", j*i, (j*i)**2)
            }
            print $Temp[j+1][1:strlen($Temp[j+1])-1].tmp_line
        }
    set print
    print $Temp2
    ### end of script
    

    Result:

     1   4  0  0  0  0  0  0
     2   5  1  1  2  4  3  9
     3   6  2  4  4  16  6  36
    

    Addition 2:

    The following is mimicing Linux' "paste" having a plot ... w table in the loop. This get's a bit ugly and requires a third datablock $Temp3. Once you appended $Temp2 to $Temp in $Temp3 you overwrite $Temp with $Temp3 and start over for the next iteration. Based on your detailed script this could maybe be simplified.

    There are some special things ongoing with the newline character, which I don't fully understand. So, apparently you have to skip the last character of the datablock line, but only for the first time (i==1). Furthermore, force the datafile separator to be space when writing to the table, otherwise it would be TAB. Mixed column separators are not nice, but gnuplot would also handle this as long as you have set datafile separator whitespace which is the default setting.

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

    ### mimic Linux' paste with gnuplot only
    reset session
    
    $Temp <<EOD
     1   4
     2   5
     3   6
    EOD
    
    do for [i=1:3] {
        set table $Temp2 separator " "
            set samples 3
            set xrange [0:2]
            plot '+' u ($1*i):(($1*i)**2) w table
        unset table
    
        set print $Temp3
            do for [j=1:|$Temp2|] {
                print $Temp[j][1:strlen($Temp[j])-(i==1)].$Temp2[j][1:strlen($Temp2[j])]
            }
        set print $Temp
            print $Temp3
        set print
    }
    
    print $Temp
    ### end of script
    

    Result:

     1   4 0   0 0   0 0   0
     2   5 1   1 2   4 3   9
     3   6 2   4 4   16 6   36