A few things are happening here. First, by default, the alignment of the text in an annotation text box is in the upper right corner. That positioning is done before the box is trimmed to the text, which leaves the text floating pretty far from the desired location. You can change this easily by adjusting the vertical alignment.
hf = figure;
for ia = 1:4
ha(ia) = subplot(2,2,ia);
end
pos = get(ha, 'position');
dim = cellfun(@(x) x.*[1 1 0.5 0.5], pos, 'uni',0);
annotation(hf, 'textbox', dim{1}, 'String', 'test 1');
annotation(hf, 'textbox', dim{2}, 'String', 'test 2', 'FitBoxToText','on');
annotation(hf, 'textbox', dim{3}, 'String', 'test 3', 'verticalalignment', 'bottom');
annotation(hf, 'textbox', dim{4}, 'String', 'test 4', 'FitBoxToText','on', 'verticalalignment', 'bottom');
The second issue has to do with the positions of the axes themselves. You'll notice that even when you fix the alignment issue, the horizontal location of the annotations overlap with the axis lines:
hf = figure;
for ia = 1:4
ha(ia) = subplot(2,2,ia);
end
arrayfun(@(x) pbaspect(x, [1 1 1]), ha);
drawnow;
pos = get(ha, 'position');
dim = cellfun(@(x) x.*[1 1 0.5 0.5], pos, 'uni',0);
for ia = 1:4
annotation(hf, 'textbox', dim{ia}, 'String', num2str(ia,'test%d'), 'vert', 'bottom', 'FitBoxToText','on');
end
This is because the axis position reflects the full potential position of the axis, rather than the space actually taken up once data aspect and plot box ratios are adjusted. I wrote a function, called plotboxpos.m, that calculates the actual space taken up by a 2D axis. If you substitute that in place of position, you can now align your annotation boxes where you want them: hf = figure;
for ia = 1:4
ha(ia) = subplot(2,2,ia);
end
arrayfun(@(x) pbaspect(x, [1 1 1]), ha);
drawnow;
pos = arrayfun(@plotboxpos, ha, 'uni', 0);
dim = cellfun(@(x) x.*[1 1 0.5 0.5], pos, 'uni',0);
for ia = 1:4
annotation(hf, 'textbox', dim{ia}, 'String', num2str(ia,'test%d'), 'vert', 'bottom', 'FitBoxToText','on');
end