MATLAB: Datetick does not set x-ticks accurately

datetickinaccurateticksx-tick

Dear all,
I am experiencing a problem with the datetick function. I am working on Matlab R2014a and the problem is the following.
I have some time series data, which I want to plot and I would like to have the x-ticks in yyyy-qq format. For this purpose I am using the functions datenum and datetick. However, dateticks generates the x-ticks sometimes inaccurately; it misses sometimes certain quarters and jumps directly to the next (e.g. the ticks are 2015-Q4 2016-Q1 2016-Q2 2016-Q3 2017-Q1), so 2016-Q4 is apparently missing. However, the space between the ticks is equal, so this must be an error.
This code reproduces the problem:
%%Problem with x-ticks using datetick
data_cpi=0.2+randn(229,1);
startDate = datenum(1998,12,1);
endDate = datenum(2017,12,1);
month = linspace(startDate,endDate,size(data_cpi,1))';
figure
plot(month,data_cpi)
xlim([month(end-36) month(end)])
datetick('x','yyyy-qq','keepticks','keeplimits')
Is this a bug and how could I fix this problem?
Thanks for the help in advance!
Best,
Diego

Best Answer

Kirby got the root cause; there's one other issue I'd warn about...I recommend strongly against using linspace or other floating point differences in computing date numbers owing to rounding issues--they may not match the precise dates desired. Instead, use the internal ability of datenum to "roll over" higher granularity time periods accounting for them internally so that the differences are integral. That is, compute your month vector as
month=datenum(1998,12+[0:12*(2017-1998)].',1);
rather than as did. I didn't test whether that may have an effect here but it definitely can if you do lookup on datenumbers in not finding a specific date that should owing to rounding in the last one or two significant bits whereas the comparisons are exact.
Anyway, on to the specifics for your case--
set(gca,'xtick',month(end-35:3:end)) % set ticks to quarters
will solve you problem; your xlim is position end-36 at December, ergo, end-35 is the Jan 1 date and the :3 delta between provides every quarter thereafter to the end point. Then you can use both 'keeplimits' and 'keepticks'.
Note that when you change xlim in HG, the number of ticks is consistent with those actually shown in that range, not just a subset with those values of the full range of values in the data vectors. That's how you can have arbitrary values of tick labels independent of the actual data values; they're not tied to each other excepting by where they're placed on the axis horizontally in relation to the axes.