gnuplot

How to transpose blocks of data (tables) within a gnuplot readable file?


How can several data blocks be transposed within a file? Each data block begins with a line '# description' and ends with two empty lines. A typical input file looks like this:

# block_01
Temp    ST_01       ST_02       ST_03       ST_04
ag7     -0.0295167  0.0553285   0.00883727  0.392553
bc9     -0.0513702  0.0355596   -0.0165404  0.252816
cc9     -0.0303508  -0.00354388 0.0428582   0.0882037
cd3     -0.0239757  -0.0363891  0.0227775   0.270722


# block_02
Temp    ST_01       ST_02       ST_03       ST_04
ag7.b   -0.00284193 0.0260536   0.163357    -0.17291
bc9.b   -0.0212977  0.0191269   0.0330521   -0.17346  
cc9.b   -0.0138837  -0.0220729  0.0814398   -0.0478094
cd3.f   -0.053152   -0.0041982  -0.0948933  -0.020557


# block_03
Temp    ST_01       ST_02       ST_03       ST_04
...

The desired output file after transposition should look as follows:

# block_01
Temp    ag7         bc9         cc9         cd3
ST_01   -0.0295167  -0.0513702  -0.0303508  -0.0239757
ST_02   0.0553285   0.0355596   -0.00354388 -0.0363891
ST_03   0.00883727  -0.0165404  0.0428582   0.0227775
ST_04   0.392553    0.252816    0.0882037   0.270722


# block_02
Temp    ag7.b       bc9.b       cc9.b       cd3.f  
ST_01   -0.00284193 -0.0212977  -0.0138837  -0.053152  
ST_02   0.0260536   0.0191269   -0.0220729  -0.0041982  
ST_03   0.163357    0.0330521   0.0814398   -0.0948933  
ST_04   -0.17291    -0.17346    -0.0478094  -0.020557


# block_03
Temp    ag7.b       bc9.b       cc9.b       cd3.f  
...

It does not necessarily have to be done only in gnuplot. Scripts in bash or awk are also welcome.


Solution

  • Here is a more general solution which is gnuplot-only (based on this solution) and works for multiple blocks each with different number of rows and columns.

    Data: SO79102179.dat

    # block_01
    Temp   a1    b1    c1    d1
    A1     11    12    13    14
    B1     21    22    23    24
    C1     31    32    33    34
    D1     41    43    43    44
    E1     51    52    53    54
    F1     61    62    64    64
    
    
    # block_02
    Temp  a2    b2    c2    d2    e2    f2
    A2    11    12    13    14    15    16
    B2    21    22    23    24    25    26
    C2    31    32    33    34    35    36
    

    Script: (works for gnuplot>=5.4.0, because of with table if ...)

    ### transpose each of multiple blocks 
    reset session
    
    FILE = "SO79102179.dat"
    
    stats FILE u (B=column(-2)) nooutput    # B = highest block index
    do for [b=0:B]{
        stats FILE index b u 0 nooutput     # get max. number of rows and columns
        R = STATS_records
        C = STATS_columns
        set datafile commentschar '' separator "\n"
        set table $Transposed append
            plot FILE index b u (_s=strcol(1)) w table if _s[1:1] eq '#'    # write comment lines
        unset table
        set datafile commentschar '#' separator whitespace  # restore default
        set table $Transposed append
            plot for [i=1:C] FILE index b u ($0==0 ? Line=strcol(i) : Line=Line.' '.strcol(i)) w table if $0==R-1, \
            '+' every ::::1 u ('') w table   # add two empty lines
        unset table
    }
    print $Transposed
    
    ### end of script
    

    Result:

    # block_01
    Temp A1 B1 C1 D1 E1 F1
    a1 11 21 31 41 51 61
    b1 12 22 32 43 52 62
    c1 13 23 33 43 53 64
    d1 14 24 34 44 54 64
    
    
    # block_02
    Temp A2 B2 C2
    a2 11 21 31
    b2 12 22 32
    c2 13 23 33
    d2 14 24 34
    e2 15 25 35
    f2 16 26 36