Search code examples
matlaboctaveaxis-labels

How do I format X Axis tick labels when using Epoch seconds as X axis values?


I have the following data set:

octave:42> yy
yy =

   1420174800.00000           21.70000           21.93000           21.64000           21.81000      1949882.00000
   1420434000.00000           21.92000           22.23000           21.90900           22.17000      3189214.00000
   1420520400.00000           22.15000           22.51000           22.08000           22.41000      4810496.00000
   1420606800.00000           22.21000           22.27500           22.07000           22.11000      2397372.00000
   1420693200.00000           21.93000           21.93600           21.70000           21.73000      2797149.00000
   1420779600.00000           21.68000           21.98000           21.68000           21.90000      2377333.00000
   1421038800.00000           21.88000           22.15000           21.87000           22.07000      2347871.00000
   1421125200.00000           21.94000           22.30000           21.76500           22.15000      5255049.00000
   1421211600.00000           22.40000           22.51900           22.24000           22.25000      5843980.00000
   1421298000.00000           22.18000           22.48000           22.14000           22.47990      3498303.00000

If I plot it I get the following chart:

octave:44> plot(yy(:,1), yy(:,5))

Chart

Following the Octave documentation (https://octave.sourceforge.io/octave/function/datetick.html) I have tried the following to get the Years displayed instead of the UNIX Epoch seconds values.

octave:48> plot(yy(:,1), yy(:,5))
octave:49> datetick('x','YYYY')

But this is the result:

enter image description here

I would like to learn how to display the YEAR (YYYY) and the year and month (YY-MM). I am not sure if a Matlab solution could also fit in Octave.


Solution

  • Short version

    plot( arrayfun( @(x) datenum([1970, 1, 1, 0, 0, x]), yy(:,1) ), yy(:,5) )
    datetick( 'x', 'yyyy' )
    

    Explanation

    The numbers you have are unix epochs (i.e. seconds since 1970-1-1 00:00:00 UTC). The reason you're getting weird numbers out of datetick is because it does not expect unix epochs as input, but "date numbers" (fractional number of days since 0000-1-0 00:00:00 UTC, whatever that means).

    What you can do, is use your values to convert to datenums, via a datevec. E.g. your first value, i.e. 1420174800, can be converted to a datenum like so

    datenum([1970,1,1,0,0,1420174800])   % i.e. the 1420174800th second of 1970-01-01 
    % ans = 7.3597e+05
    
    datestr( datenum([1970,1,1,0,0,1420174800]), 0 )
    % ans = 02-Jan-2015 05:00:00
    

    Therefore, you could convert all your unix epochs to datenums, e.g. like so

    DateNums = arrayfun( @(x) datenum([1970, 1, 1, 0, 0, x]), yy(:,1) )
    

    And then plot using the DateNums instead, and use datetick as expected.

    The above solution would work identically in octave and matlab.