Search code examples
plotgnuplot

Gnuplot - a way to convert and plot text information?


I am trying to use gnuplot to display the information contained in a file as in the example below:

    1           2                   3                   …   10    11
    1           1.0000000e-06       1.0000000e-06       …   0 
    2           2.5000000e-06       1.5000000e-06       …   0     #dt_grow
    3           4.7500000e-06       2.2500000e-06       …   0     #dt_grow
    4           8.1250000e-06       3.3750000e-06       …   0     #dt_cfl
    5           1.2450703e-05       4.3257029e-06       …   1     #dt_mach, max_iteration_turbulence
    6           1.6811013e-05       0.3603104e-06       …   0     #dt_grow

My goal is to be able to represent, somehow, the information listed in column 11 which, as you can see, contains non-numeric characters.

It might be pointless but, before moving ahead, it might be helpful to stress that:

  1. row1 has no value at column 11
  2. each column 11 value start with # and is not quoted
  3. column 11 contains many other different possible entries (e.g. "#dt_piso","#dt_piso, 2*max_piso reached", "#dt_mach, temperature extrapolation error")
  4. when values of column 11 present an additional information (e.g ", max_iteration_turbulence") values of column 10 are non-zero
  5. the number of rows is typically of the order 10^6

My idea was to use associate a numeric value to each element of column11 using functions (e.g. if #dt_grow then 1, if #dt_cfl then 2 ecc) so that I can somehow represent this information.

What I have tried so far produce nothing but errors (that I am for brevity listing below each used plot command):

p "file" u 1:11 w l
--> x range is invalid

p "file" u 1:(''.$11 eq "#dt_cfl" ? 1 : 0) w l
--> warning: Skipping data file with no valid points. x range is invalid

p "file" u 1:(column(11) eq "#dt_cfl" ? 1 : 0) w l
--> internal error : STRING operator applied to non-STRING type

p "file" u 1:(strcol(11) eq "#dt_cfl" ? 1 : 0) w l
--> internal error : STRING operator applied to non-STRING type

splot "time.out" u 1:(11 eq "#dt_cfl" ? 1 : 0) w l
--> Need 1 or 3 columns for cartesian data

#Usage of functions does not resolve the issue:
e.g. f(x)= ''.x eq "#dt_cfl" ? 1 : 0

As you can probably tell by the diversity of my trials I am somehow confused on how it is recommendable to proceed in such cases. I have never had to plot string data and I am not quite sure of what is causing the issue. I've been looking for some inputs on the documentation but nothing really helped me on this. I would very much appreciate any inputs on how to handle string data and associate them to numeric values.

To wrap it up: I want to display the evolution of the information on column 11. Ideally, I would like to be able to use the eventual additional information (as explained in point 4 above) based on the value of column 10.

Based on my request I believe a python script could better fit my necessities, but I am wondering if gnuplot offers such possibilities and I am eager to learn more.

Thanks in advance :)!

P.S.: I am adding a sketch of the results I am trying to obtain hping that this can help clarify my goals. I am anyway open to new solution as this is just my plan of how I was thinking about overcoming the problem of plotting text data. With respect to the few rows of data that provided above and assuming to do the following assosiations:

  • #dt_grow is 1
  • #dt_cfl is 2
  • #dt_mach is 3
  • so on for other possible values (this could be hardcoded as I would have no more that 10 possible values in column11)

Plot_ sketch


Solution

  • Maybe something like this? You can use the 11th column (here: 5th column) as x2ticlabels (check help xticlabels). Before, link the x2 axis to the x1 axis (check help link). You could rotate the x2tic labels if they are getting to many and overlap: set x2tics rotate by 90. In principle, you could get rid of the leading # of each label, but I guess it will get a bit tricky because of your missing value in row 1. Look at the example below as a starting point.

    Script:

    ### adding text info from columns to some labels
    reset session
    
    $Data <<EOD
        1   2               3               4     5
        1   1.0000000e-06   1.0000000e-06   0
        2   2.5000000e-06   1.5000000e-06   0     #dt_grow
        3   4.7500000e-06   2.2500000e-06   0     #dt_grow
        4   8.1250000e-06   3.3750000e-06   0     #dt_cfl
        5   1.2450703e-05   4.3257029e-06   1     #dt_mach, max_iteration_turbulence
        6   1.6811013e-05   0.3603104e-06   0     #dt_grow
    EOD
    
    set termoption noenhanced
    set key top left 
    set link x2 via x inverse x
    set x2tics
    
    plot $Data u 1:2:x2tic(5) skip 1 axes x2y1 w lp pt 7 lc "red"       title "column 2", \
            '' u 1:3          skip 1           w lp pt 7 lc "web-green" title "column 3"
    ### end of script
    

    Result:

    enter image description here

    Addition:

    I guess I understand what you want to do but the background is still a bit unclear. What you are asking for is a conversion or mapping of strings to numbers. I assume you have a fixed and known set of keywords. Apparently, for your desired plot the other columns besides 1 and 11 do not play a role. Your missing value in column 11 in row 1 (excl. header) will create problems, hence add the option skip 2. In the minimized example below, your column 11 is actually column 2. The example below will create some random test data for better illustration.

    • create a string list of your keywords
    • you can address them via word(), check help word
    • you can (mis)use sum for a lookup to get the index, check help sum
    • furthermore, check help strcol, help xticlabels, help skip, help ternary.

    Script:

    ### map strings to numbers
    reset session
    
    myKeys   = '#dt_grow #dt_cfl #dt_piso #dt_foo #dt_bar #dt_xyz #dt_abc'
    myKey(i) = word(myKeys,i)
    
    # create some random test data
    set table $Data
        set samples 50
        plot '+' u ("1 2") every ::0::0 w table
        plot '+' u ("1")   every ::0::0 w table
        plot '+' u ($0+1):(word(myKeys,int(rand(0)*words(myKeys)+1))) w table
    unset table
    
    getIdx(s) = (n=0, sum[i=1:words(myKeys)] (s eq myKey(i) ? n=i : 0), n)
    set ytics 1
    set grid x,y
    
    plot $Data u 1:(y0=getIdx(strcol(2))):ytic(myKey(y0)) skip 2 w lp pt 7 lc "red" notitle
    ### end of script
    

    Result:

    enter image description here