Search code examples
timegnuplotxrange

gnuplot: plot data from one month ago to now


everyone.

I have some data which periodically updated. For example:

1330347541 79 100 6 163 38
1330349341 80 103 6 165 38
1330351141 80 104 6 166 40
1330352941 80 104 6 166 40
1330354741 81 104 8 167 41

I want to draw that data on a graph with gnuplot.

How can I draw data from one month ago to now? Which xrange I need to choose?

Edit: I need something like "set xrange [now - 2592000, now]"


Solution

  • I had a similar problem. Although you didn't show exactly how you were doing the plot. I wished to set the range using timestamps and found something unexpected . . . so although oldish I think it's worth answering this question.

    Two useful things:

    1. You can plot with xrange set to [*.*] and then 'show xrange' to find out what internal represantation of the xrange is being used by your gnuplot.

    2. You can use () in gnuplot to insert calculations and function calls.

    Answer #1 Are you plotting using timecolumn? Prior to gnuplot 4.7 gnuplot internal times were tracked relative to 1-Jan-2000, not unix epoch 1-Jan-1970. The answer depends on what version of gnuplot are you using? You can use () in gnuplot to do call functions or do calculations. You can call out to shell command date to get timestamp. So . . .

    set xrange [(system("date -d 'now' +%s")-2592000):(system("date -d 'now' +%s"))]
    show xrange
        set xdata time
        set xrange [ "1431007547" : "1431008547" ] noreverse nowriteback
    

    Prior to gnuplot 4.7 you also have to subtract 946684800 seconds from all timestamps. ACTUALLY I have found about 1893370441 secs =~ 60 years is the value I have to subtract with my version of gnuplot (4.6). Find the timestamp offset by doing a plot with your timestamp data without setting xrange and then do a 'show xrange' and calculate the offset.

    So define offset used and set xrange as follows:

    ####################################################################
    ## 1893456000 = 60 years seems to be the offset gnuoplot is using.##
    ## or is it 1893370441 ? yeah it seems to be a bit short of 60 years.
    ## I believe 946684800 should be the offset prior to 4.7.         ##
    ####################################################################
    TIMEOFFSET=946684800
    TIMEOFFSET=1893370441
    set xrange [(system("date -d 'now' +%s")-2592000-TIMEOFFSET):(system("date -d 'now' +%s")-TIMEOFFSET)]
    

    Answer #2 Is your xrange actually in data file rows? (i.e. not using timecolumn). In that case set your xrange in terms of data rows. If your data is periodic you could calculate how many rows back = a particular time period.

    I happen to be using this version of gnuplot:

        Version 4.6 patchlevel 1    last modified 2012-09-26 
    

    MORE details and exploration ...

    Do a basic plot of your data:

    set xdata time
    set timefmt "%s"
    set timefmt x "%s"
    set format x "%H:%M"
    plot "lollo.data" using 1:2, "lollo.data" using 1:3
    

    Okay, now set a simple xrange from first to last timestamp in data.

    set xrange [1330347541:1330351141]
    plot "lollo.data" using 1:2, "lollo.data" using 1:3
                                                   ^
         all points y value undefined!
    

    Woah!? Really? What is wrong with that? Let's do 'show xrange' to see what gnuplot thinks the range is.

    show xrange
        set xdata time
        set xrange [ "1330347541" : "1330351141" ] noreverse nowriteback
    

    That looks okay. Let's set the xrange to *:* (what gnuplot starts off with (you can also do 'set xrange restore' BUT that sets it to [-10:10] - not what we want)), do a plot and THEN show xrange.

    set xrange [*:*]
    plot "lollo.data" using :2, "lollo.data" using :3
    show xrange
        set xdata time
        set xrange [ * : * ] noreverse nowriteback  # (currently ["0":"4"] )
    

    Hmmmn. 0:4 !! Interesting. Looks like the xrange is operating on rows of data not in time. So. Is this your problem? Assuming xrange would be working in timestamps and not rows? Knowing this you may be able to set your xrange in terms of rows. == Answer #2

    Now. Let's plot the data using timecolumn.

    set xrange [*:*]
    plot "lollo.data" using (timecolumn(1)):2, "lollo.data" using (timecolumn(1)):3
    show xrange
        set xdata time
        set xrange [ * : * ] noreverse nowriteback  # (currently ["-563022900":"-563014800"] )
    

    Whoooops! -563022900 !? A negative timestamp. Interesting. So timestamp integer calculation weirdness/feature in this version of gnuplot?

    Let us try and set the simple xrange from first to last timestamp in data and plot using timecolumn.

    set xrange [1330347541:1330351141]
    plot "lollo.data" using (timecolumn(1)):2, "lollo.data" using (timecolumn(1)):3
                                                                               ^
         all points y value undefined!
    

    It doesn't like that. Understandable if it is working off negative timestamp numbers internally.

    Let's set the negative range LESS one month of seconds using () to surround calculation:

    set xrange [(-563014800-2592000):-563014800]
    plot "lollo.data" using (timecolumn(1)):2, "lollo.data" using (timecolumn(1)):3
    

    That works. For me. gnuplot 4.6. But where did -563014800 come from!?

    $ date -d @1330347541
    Mon 27 Feb 12:59:01 GMT 2012
    $ dc -e '1330347541 16o p'
    4F4B7E15
    ### ??? I didn't find any hex relation - looking for evidence of integer calc overflow/sign calc errors
    
    # What offset 
    $ dc -e '0 1330347541 - 563022900 - p'
    -1893370441
    # taking a timestamp from today (7 march 2015) and doing a plot I saw gnuplot used xrange with -462448800 . . . 
    $ dc -e '0 1431000097 - 462448800 - p'
    -1893448897
    

    HAH! It is about the same. -1893448897 =~ -1893370441 That is just about 60 years. SO. A 60 year offset is being used. In my version of gnuplot. INTERESTING. and YEESH. SO I seem to need to subtract about 1893456000 secs to convert to internal gnuplot timestamp. Actually 1893370441 seems closer to what is needed.

    Elsewhere on the internet gnuplot's epoch is said to be in the year 2000. Which should mean an offset of 946684800 should be used. But that doesn't seem to be the case for me right now.

    YMMV. I guess.

    Using that offset you can set xrange from one month ago to now like this: == Answer #1

    TIMEOFFSET=1893370441
    set xrange [(system("date -d 'now' +%s")-2592000-TIMEOFFSET):(system("date -d 'now' +%s")-TIMEOFFSET)]
    

    And how/why is this the case in gnuplot?

    From: http://gnuplot.10905.n7.nabble.com/30-year-time-offset-reading-nonuniform-matrix-s-input-td17231.html "Sorry, I think it was probably me. I didn't use unix back then, so 2000 seemed as arbitrary as 1970.

    Originally it wasn't intended that it be visible to the user anyway, but it was discovered later that you could use numbers rather than strings in things like setting ranges for time data.

    I think I also had in mind that, because time was stored a real number, it wasn't good to carry a large offset around since that limited the resolution available for small numbers. But I think that's probably not relevant in practise.

    Dave D"