Search code examples
plotgraphrowgnuplot

gnuplot: How to add a new colored curve every nth row while removing intermediate headers?


I've got a file which has this structure:

Header 1
Header 2
config X Y
0.0 -5 -2
0.0 0 1
0.0 5 4
Header2
Config X Y
1.0 -5 -1
1.0 0 0
1.0 5 5
Header2
Config X Y
2.0 -5 0
2.0 0 1
2.0 5 6

Using gnuplot, I would like to plot columns 2:3 (Y as a function of X) with a few conditions:

  • Get rid of the headers and any line that's not filled with numbers
  • On the same graph, plot a new function (with a new label and a new color) each time the config changes. In the aforementioned case, you'd end up with three plots (one for config=0.0, one for config=1.0 and one for config=2.0)

Is there a one-liner for this in Gnuplot?

I tried to use the "every" keyword

p 'filename.txt' every ::3 u 2:3 w p

but to no avail

Thank you


Solution

  • If you have a strict data structure and you insist on a one-liner you could do the following with every, check help every. However, then you need to know in advance that N=5 (here: 2 header lines and 3 data lines) and you have 3 blocks. You also skip the first 3 lines (check help skip).

    You could use stats find out N automatically. Personally, I would prefer a solution with more than one line, which would robust against little changes in data, just in case.

    Script:

    ### separate data into subblocks with different colors
    reset session
    
    $Data <<EOD
    Header 1
    Header 2
    config X Y
    0.0 -5 -2
    0.0  0  1
    0.0  5  4
    Header2
    Config X Y
    1.0 -5 -1
    1.0  0  0
    1.0  5  5
    Header2
    Config X Y
    2.0 -5  0
    2.0  0  1
    2.0  5  6
    EOD
    
    plot for [i=0:2] N=5 $Data u 2:3 every ::i*N::(i+1)*N-1 skip 3 w lp pt 7 lc i ti sprintf("Config%d",i)
    ### end of script
    

    Result:

    enter image description here

    Addition:

    Here is a more general (but maybe not too obvious) solution:

    • you don't need to know in advance how many blocks you have and how many datalines you have
    • you can have different number of data lines

    What the script does:

    • during plotting, the script checks if the column 1 contains a valid number, valid(1) will return 1 if it is a valid number and 0 otherwise (check help valid).
    • the variable c1 is initialized to 0. During plotting line by line c0 is assigned the value of c1 and c1 gets the value of valid(1).
    • so, everytime column 1 changes from text to numbers (i.e. c1>c0) increment b by 1 and use it for setting the color (check help lc variable)
    • plot keyentries in a loop with the corresponding title.

    So, it is a two-liner which also could be put into a single line.

    Script:

    ### separate data into subblocks with different colors (more flexibility)
    reset session
    
    $Data <<EOD
    Header 1
    Header 2
    Header 3
    config X Y
    0.0 -5 -2
    0.0  0  1
    0.0  5  4    # could be followed e.g. by an empty line
    
    Header2
    Config X Y
    1.0 -5 -1
    1.0  0  0
    1.0  5  5
    1.0  6  6   # 4 data entries
    Header2
    Config X Y
    Some other text line added
    2.0 -5  0
    2.0  0  1
    2.0  5  6
    2.0  6  7
    2.0  7  6.5   # 5 data entries
    EOD
    
    set key top left noautotitle
    
    plot c1=b=0 $Data u (c0=c1,c1=valid(1),$2):($3):(c1>c0?b=b+1:b-1) w lp pt 7 lc var, \
         for [i=0:b-1] keyentry w lp pt 7 lc i ti sprintf("Config%d",i)
    ### end of script
    

    Result:

    enter image description here