Search code examples
linuxgnuplot

How to read data from a logfile into variables and plot them against each other in gnuplot?


I have a log file which is being updated continuously by a process being run on Linux. I am trying to plot Var1(Y axis) vs Var2(X axis). My current script plots them individually that is, it will will plot Var1 vs indexed values and, Var2 vs indexed values.

Since the log file is being updated continuously, I am re-reading the data.

How can I set the X axis values from Var2 ?

set title "Var1 vs Var2"
set xlabel "Var2"
set ylabel "Var1"

Var1="< cat ./output.txt | grep -w 'Mean and max values' |  cut -d' ' -f 9"
Var2="< cat ./output.txt | grep -w 'Time =' | cut -d'=' -f 2"

plot Var1,Var2 using lines

pause 2
reread

I have tried setting xtics values using set xtics (Var2) but it doesn't work.


Solution

  • Although a solution using cat, grep, awk, etc... might be easier, but I prefer gnuplot-only solutions which are also platform-independent.

    The following solution is not obvious and probably needs some explanations:

    • first set datafile separator to newline "\n". This means the variable s=strcol(1) contains the complete line
    • initialize m and t to NaN
    • if s begins with your first key Courant Number mean: m will get the 6th token (i.e. the maxium value)
    • if s begins with your first key Time =, t will get the 3th token (i.e. the time value).
    • only if m and t are not NaN plot m as y value and set t=NaN.

    So, the plot command will go through the file and plot the found t versus the previously found m.

    Furthermore:

    • use while for a loop which you can stop by pressing x. Check help bind.
    • since I don't have changing data, the script shows a random color for each pass of the loop.
    • if you want to plot it with connected lines or linespoints you have do some extra steps via a table to remove the interruptions.

    Data: SO75929902.dat (just a small excerpt from your file)

    Courant Number mean: 8.74894e-05 max: 0.0315889
    Time = 1e-05
    
    PIMPLE: iteration 1
    diagonal:  Solving for rho, Initial residual = 0, Final residual = 0, No Iterations 0
    smoothSolver:  Solving for Ux, Initial residual = 1, Final residual = 8.57331e-06, No Iterations 1
    ...
    ...
    ...
    fieldAverage fieldAverage1 write:
        Calculating averages
    
    Courant Number mean: 0.0294733 max: 0.506002
    Time = 0.0004
    
    PIMPLE: iteration 1
    diagonal:  Solving for rho, Initial residual = 0, Final residual = 0, No Iterations 0
    ...
    

    Script:

    ### extract and plot values from a regularly updated file in a loop
    reset session
    
    FILE = "SO75929902.dat"
    
    key1 = "Courant Number mean:"
    key2 = "Time ="
    
    set datafile separator "\n"
    set key noautotitle
    set grid x,y
    
    continue = 1
    bind x   "continue = 0"
    
    while (continue) {
        plot m=t=NaN FILE u (s=strcol(1), s[1:strlen(key1)] eq key1 ? m=real(word(s,6)) : NaN, \
             s[1:strlen(key2)] eq key2 ? t=real(word(s,3)) : NaN, t) : \
             (m==m && t==t ? (t=NaN, m) : NaN) w lp pt 7 lc rand(0)*0xffffff
        pause 2
    }
    ### end of script
    

    Result: (using wxt terminal)

    enter image description here

    Addition:

    I cannot help with cat, grep, sed, awk, etc., however, let's assume you have your data separated by spaces in two strings (varX and varY). Then you can use the special filename '+' (check help special-filenames), the sampling (check help samples) and the pseudocolumn 0, i.e. row number zero-based (check help pseudocolumns). You need to set the start of the xrange[0:] manually, because default range would be [-10:10].

    Script:

    ### plot data from two strings
    reset session
    
    varX = "1 2 3 4 5 6 7 8 9"
    varY = "9 5 6 3 7 4 8 2 1"
    
    set samples words(varX)
    x(col) = real(word(varX,int(column(col)+1)))
    y(col) = real(word(varY,int(column(col)+1)))
    
    set xrange[0:]
    
    plot '+' u (x(0)):(y(0)) w lp pt 7 lc "red"
    ### end of script
    

    Result:

    enter image description here