How to define the (minimum) number of ticks with "ytick mode auto"
14 views (last 30 days)
Show older comments
Hi, to emphasize possible nonlinearities in scaling I need to have a minimum number of ticks, more than two for positive data, or mor than three for data if zero is included.
I am aware of all the "official" properties, such as YLim, YTick, YTickMode, YTickLabel, etc.,
But how to get more than three ticks when data are centered around zero automatically?
Or, when using the manual mode, how to get "nice numbers" as it is done within the "auto" tick mode function? E.g., such that Zero is included, the data are "round" and symmetric?
13 Comments
Sam Chak
on 5 Sep 2025
Hi @Andre Zeug, Thanks for your updates. It is good to know that you have adopted @Stephen23's niceTicks(). If you find the solution helpful and satisfactory, please consider clicking 'Accept' ✔ on his answer, as well as voting for other helpful contributions by the others.
Answers (1)
Stephen23
on 4 Sep 2025
Axes do not expose a “minimum tick count” property. In auto mode the tick positions are chosen internally from the axis limits, the figure size and the font size; you cannot tell the axes to “use at least N ticks”. The only time you have full control over tick placement is when you switch the ruler into manual mode and set the TickValues/YTick vector yourself:
If you want a custom number of ticks with “nice” values you therefore have to compute the ticks and pass them to the axis. There is no built‑in function that does this automatically, but you can implement the common “nice number” algorithm. The idea is to compute a raw spacing equal to (maxVal–minVal)/(numTicks-1), round this to a “nice” value (multiples of 1, 2, 2.5, 5, … × 10^n), and then generate tick positions that include zero if it lies in the range. Below is one possible implementation that tries to hit your requested number of ticks but uses “nice” spacing. When zero is in the range an odd number of ticks gives a symmetrical tick at zero; even numbers are likely to require an extra tick.
function ticks = niceTicks(minVal,maxVal,numTicks)
if minVal==maxVal
ticks = minVal;
return
elseif minVal>maxVal
[minVal,maxVal] = deal(maxVal,minVal);
end
includeZero = (minVal <= 0 && maxVal >= 0);
% Raw spacing and exponent
rawStep = (maxVal-minVal)./(numTicks-1);
exponent = floor(log10(rawStep));
baseStep = 10.^exponent;
% Candidate multipliers for “nice” spacing
mult = [1,2,2.5,5,10];
bestDiff = Inf;
for m = mult
step = m*baseStep;
tMin = floor(minVal/step)*step;
tMax = ceil (maxVal/step)*step;
ticks = tMin:step:tMax;
if includeZero && ~ismember(0,ticks), ticks = sort([ticks 0]); end
ticks = ticks(ticks>=minVal & ticks<=maxVal);
difft = abs(numel(ticks) - numTicks);
if difft < bestDiff || (difft==bestDiff && numel(ticks)>=numTicks)
bestTicks = ticks;
bestDiff = difft;
end
end
ticks = bestTicks;
end
You can call this function and then set the axis ticks manually:
x = linspace(0,10,100);
y = sin(x);
numTicks = 5;
ticks = niceTicks(min(y),max(y),numTicks)
plot(x,y);
ylim([min(y) max(y)]);
set(gca,'YTick',ticks) % fix tick positions
For your examples:
niceTicks(-5,5,5)
niceTicks(-0.17,0.12,5) % (six ticks because of zero)
niceTicks(0.003,0.12,5)
This approach gives you “round” tick values and includes zero when it lies in the range. When the requested count cannot be achieved exactly with “nice” spacing, the function favours having more ticks rather than fewer so that the non‑linear scaling is visible. If you need an exact number of tick labels regardless of “niceness” you can fall back on a simple linspace(minVal,maxVal,numTicks) call and use sprintf or YTickLabelFormat to format the numbers.
2 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!