Search code examples
gnuplot

Make gnuplot's x axis start at 0 instead of the first date


I'm plotting some [date, value] formatted data (cpu use over time) and want the xtics to start at 0 or 1 instead of the first date.

So for 10 hours it should look like: 0:01:00, 0:02:00, .., 0:10:00 insead of 9:23:00 ... (since the first day in the data is the 9th at 11pm).

My current datetime settings:

set xdata time
set timefmt "%Y-%m-%d %H:%M:%S"
set xtics format "%d:%H:%M" font ",25"

Edit: If there's a way to just count hours starting from 0 on the x axis without day info that'd be awesome too. Either way. I just want to start counting from 0 to make the "time taken" very clear.


Solution

  • I couldn't get it to work with set xdata time, because for the output only the day of the month is available, which is in the range [1:31], so the 0-position would start with 1. The same happens for total number of hours, because that value is limited to [0:23], so that number over 23 are wrapped back.

    Here is a solution without time data. I use the strptime function to convert the date string to a time stamp (in seconds), which is then divided by 3600 to get the hour (as float number):

    The test data file is:

    2013-08-25 18:45:11 100
    2013-08-25 19:11:23 200
    2013-08-25 20:00:32 400
    2013-08-25 21:00:32 300
    2013-08-26 20:11:12 500
    

    And the example script:

    reset
    file='data.txt'
    fmt="%Y-%m-%d %H:%M:%S"
    start=system('head -1 '.file)
    start_stamp = strptime(fmt, start)
    plot 'data.txt' using ((strptime(fmt, stringcolumn(1).' '.stringcolumn(2))-start_stamp)/3600.0):3 with lines t ''
    

    The first column is extracted with an external tool.

    The result is:

    enter image description here

    And here is another variant, which uses a more comfortable data format, using commas as separators, and the first column is extracted with gnuplot:

    The data file:

    2013-08-25 18:45:11,100
    2013-08-25 19:11:23,200
    2013-08-25 20:00:32,400
    2013-08-25 21:00:32,300
    2013-08-26 20:11:12,500
    

    The script file:

    reset
    file='data.txt'
    fmt="%Y-%m-%d %H:%M:%S"
    set datafile separator ','
    plot 'data.txt' using ($0 == 0 ? start_stamp = strptime(fmt, stringcolumn(1)) : 0, \
         (strptime(fmt, stringcolumn(1))-start_stamp)/3600.0):2 with lines t ''
    

    The results are equivalent.

    EDIT: One last variant, which is a mixture @andyras's and my answer. You can use set timefmt with an explicit call to timecolumn to parse the input as time. The output is then handled like a conventional double number. I use $0, i.e. the number of the current sample, to set the offset value:

    reset
    set timefmt "%Y-%m-%d %H:%M:%S"
    
    offset = 0
    t0(x)=(offset=($0==0) ? x : offset, x - offset)
    
    plot 'data.txt' u (t0(timecolumn(1))/3600.0):3 notitle w l