Search code examples
gnuplot

Format date/time axis in Gnuplot


I have the following data series:

201708201600 1.175588 1.175631 1.175553 1.175591
201708202000 1.175564 1.175604 1.175520 1.175561
201708210000 1.174651 1.174711 1.174582 1.174644
201708210400 1.174855 1.174935 1.174785 1.174862
201708210800 1.179250 1.179381 1.179146 1.179268
201708211200 1.181497 1.181555 1.181437 1.181495
201708211600 1.181187 1.181228 1.181142 1.181185
201708212000 1.181156 1.181195 1.181113 1.181151
201708220000 1.179908 1.179969 1.179837 1.179902
201708220400 1.176303 1.176397 1.176190 1.176293
201708220800 1.176182 1.176286 1.176073 1.176177
201708221200 1.175669 1.175722 1.175607 1.175667
201708221600 1.176249 1.176292 1.176201 1.176249
201708222000 1.175689 1.175735 1.175640 1.175687
201708230000 1.175872 1.175956 1.175803 1.175881
201708230400 1.178496 1.178590 1.178409 1.178501
201708230800 1.180339 1.180446 1.180235 1.180339
201708231200 1.181056 1.181128 1.180989 1.181063
201708231600 1.181169 1.181212 1.181126 1.181168
201708232000 1.180509 1.180546 1.180466 1.180502
201708240000 1.179841 1.179903 1.179779 1.179836
201708240400 1.179210 1.179283 1.179138 1.179215
201708240800 1.180083 1.180180 1.179983 1.180079
201708241200 1.180609 1.180661 1.180560 1.180609
201708241600 1.179991 1.180023 1.179961 1.179991
201708242000 1.179487 1.179522 1.179448 1.179485
201708250000 1.179193 1.179242 1.179133 1.179185
201708250400 1.180497 1.180586 1.180420 1.180508
201708250800 1.183690 1.183868 1.183538 1.183712
201708251200 1.189021 1.189156 1.188896 1.189041
201708251600 1.192202 1.192281 1.192131 1.192194

Where first column represent a date/time YYYYMMDDhhmm.

Which means that in this particular example there is data every 4 hours.

I need to get:

  1. a major tick in x axis everyday at 00:00 where the month and day is displayed
  2. a minor tick in x axis without label text every 4 hours.

I have tried:

set timefmt "%Y%m%d%H%M"
set format x "%b %d"
set xdata time

Which effectively formats date/time as month name and day number.

How can it be done to force major ticks take place every day and rest of the data be minor ticks?

So in this case I would like major ticks on:

-      (2 minor ticks for 16:00 and 20:00)
Aug 21 (6 minor ticks for 00:00 to 20:00)
Aug 22 (6 minor ticks for 00:00 to 20:00)
Aug 23 (6 minor ticks for 00:00 to 20:00)
Aug 24 (6 minor ticks for 00:00 to 20:00)
Aug 25 (6 minor ticks for 00:00 to 20:00)
Aug 26 (5 minor ticks for 00:00 to 17:00)

So the idea is that we mark a tick every 4 hours (as per the data) but the text only appears at the beginning of a new day, which would make the chart easy to read.


Solution

  • First the easy solution, which may or may not suit your general case:

    # Option 1:  tic pattern is independent of data in file
    # Set one major tic per day with minor tics every 4 hours
    seconds_per_day = 60.*60.*24.
    set xtics seconds_per_day
    set mxtics 6
    

    If you really need one tic per data entry with no extras, then it gets more complicated. First note that this command will place a tic mark for each entry in the file, but none of them have labels:

    plot 'time.dat' using 1:2:xtic("") with lp
    

    Now let's expand that by defining a label function that reads a string from column N and prints an empty label unless the final four characters are 0000 (i.e. midnight). At midnight it reformats the time value to your preferred "%b %d":

    label(N) = (strcol(N)[9:12] eq "0000") \
             ? strftime("%b %d",timecolumn(N,"%Y%m%d%H%M")) \
             : ""
    

    The complete plot command then looks like this

    plot 'time.dat' using 1:2:xtic(label(1)) with lp