MATLAB: How to write in the middle of ticks

minorticktick

Hello Everybody.
I have a graph with my major ticks setted on 1 Janauary of each Year. I want to be able to write the year in the middle, so using I guess a Minortick and as it was set at June of each year. And of course, i would like to delay the xticklabels
I cannot understand honestly how to do, in the massive jungle of minorticks and ticks.
Thank you for your helping in advance!

Best Answer

Datetime x-ticks for 6-month intervals
It looks like you want to set xtick, not minor ticks.
If your data are in datetime format and you want half-year ticks on January 1st and July1st for every year,
% dt is your datetime vector.
% Create vector of Jan 1st /July 1st dates spanning the range of your data.
startDate = dateshift(min(dt), 'start', 'year');
endDate = dateshift(max(dt), 'start', 'year') + calyears(1);
dtTicks = startDate : calmonths(6) : endDate;
% set ticks
set(gca, 'XTick', dtTicks, 'xlim', dtTicks([1,end])) % xlim optional
You can edit for datetime tick format using
datetick('x','mmm-yy','keeplimits','keepticks')
% or
datetick('x','QQ-yyyy','keeplimits','keepticks')
Demo
dt = datetime(2005,03,16) + caldays(0:20:1000);
data = (0:20:1000).^2;
plot(dt, data, 'o')
To place labels between ticks
Since Matlab does not support minor-tick labels, and since we cannot specify the position of a tick label independently from the tick positions, you'll have to use a workaround.
One workaround is to use text objects as xtick labels but that gets sloppy when the figure is resized or the axis limits are changed.
Another workaround is to add a 2nd underlying axis that controls the xtick labels while the main axis controls the xticks. That's demonstrated below. See inline comments for details.
% Create demo data
dt = datetime(2005,03,16) + caldays(0:20:3000);
data = (0:20:3000).^2;
% Create main axis and an underlying axis to control xticklabels.
axUnder = cla(); % Underlying axis handle
ax = copyobj(axUnder, ancestor(axUnder,'figure')); % main axis handle.
% Plot data on main axis (ax)
plot(ax, dt, data, 'o')
% Compute start|end date, both on Jan 1 of some year
startDate = dateshift(min(dt), 'start', 'year');
endDate = dateshift(max(dt), 'start', 'year') + calyears(1);
% Compute 6-month interval date ticks
dtTicks = startDate : calmonths(6) : endDate;
% Set xticks of the main axis to Jan 1st of each year but remove labels
xticks = dtTicks(1:2:end);
xtickLabs = repmat({' '},size(xticks)); % to get the xlabel spacing right
set(ax, 'XTick', xticks, 'XLim', [min(dtTicks),max(dtTicks)],'XTickLabel', xtickLabs)
% Set xticks of underlying axis to July 1st of each year, use Jan 1st tick labels
% We also need to plot an invisible data point on the underlying axis to force the
% xaxis to be datetimeruler.
plot(axUnder, dt(1), nan, 'x') % will not appear.
dtTicksLabs = cellstr(datestr(dtTicks(1:2:end),'yyyy'));
set(axUnder, 'XTick', dtTicks(2:2:end),'XTickLabel', dtTicksLabs, 'xlim', ax.XLim)
axUnder.YTick = [];
% Set title and axis labels
title(ax, '9-year trends')
xlabel(ax, 'Years')
ylabel(ax, 'stuff (units)')
% Equal axes positions and xlim so fig-resize doesn't mess things up.
% Must come after converting axUnder to datetimeruler.
linkprop([ax,axUnder],{'Position','InnerPosition','XLim'}); % add more as needed
axUnder.HandleVisibility = 'off'; % avoid accidentally accessing the underlying axis