I am creating a multi-panel figure in MATLAB (with multiple axes of different size). I would like all tick marks to have the same absolute size across all subplots.
According to the MATLAB user guide, tick length is normalized with respect to the longest axis:
TickLength. Tick mark length, specified as a two-element vector of the form [2Dlength 3Dlength]. [...] Specify the values in units normalized relative to the longest of the visible x-axis, y-axis, or z-axis lines.
In order to make all ticks of the same length, I am running the following code:
fixlen = 0.005; % Desired target length
for i = 1:numel(h) % Loop over axes handles
rect = get(h(i),'Position'); % Get the axis position
width = rect(3); % Axis width
height = rect(4); % Axis height
axislen = max([height,width]); % Get longest axis
ticklen = fixlen/axislen; % Fix length
set(h(i),'TickDir','out','TickLength',ticklen*[1 1]);
end
Unfortunately, the above code does not produce a figure in which all tick lengths are equal. Perhaps I am missing something?
Solution. There were two problems in my code.
First of all, I needed to switch from Normalized
units to some fixed units (such as pixels). See the answer below.
In some part of the code, before the above snippet, I was resizing the figure and I had a drawnow
to update it. However, MATLAB would reach the code snippet before the graphics commands had been executed, and therefore the reported sizes were not correct. I solved the issue by placing a pause(0.1)
command after the drawnow
.
By default, Axis
objects have their Units
property set to normalized
. This means that the values in the Position
property are normalized by the size of the figure. Hence your code may not be producing the desired behavior if the figure is not square.
One way to fix this is the following:
rect = get(h(i),'Position'); % Axis position (relative to figure)
hfig = get(h(i),'Parent'); % Handle to parent figure
rectfig = get(hfig, 'Position'); % Figure position (in pixels)
width = rect(3) * rectfig(3); % Absolute width of axis (in pixels)
height = rect(4) * rectfig(4); % Absolute height of axis (in pixels)
This will give you width/height in terms of pixels on your screen (assuming that you didn't change the Units
property of the figure).
And if you use rectfig = get(hfig,'PaperPosition')
then you will get width/height in terms of inches on the printed page (again, assuming default value for the figure's PaperUnits
property).
Note, however, that you will need to adjust the value you use for fixlen
to match the new units we're using here.