How to define the (minimum) number of ticks with "ytick mode auto"
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
Mathieu NOE
on 4 Sep 2025
hello
what is the problem ?
if you know how to use YLim, YTick, YTickMode, YTickLabel,... and data formatting you can do anything you want
do you have an example / code ?
Mathieu NOE
on 4 Sep 2025
sorry but I am still unsure to fully understand what you want to do
if I try to sum up what I have understood so far (guessing somehow)
if data is strictly pos or neg : output must be at least two ticks with TBD rounding
if it includes zero then one more tick (zero obviously)
then the general case with pos and neg data : I assume you want the zero tick
+ how many pos ticks and how many neg ticks ?
with equal spacing or equal number of ticks ? , symetrically arranged ? in the last case you may have a different spacing in neg and pos ticks ...
Sam Chak
on 4 Sep 2025
Hi @Andre Zeug
Could you specify the desired ticks for Case 2 and Case 3? This will allow us to verify the formulas and functions used in your code.
Andre Zeug
on 4 Sep 2025
Mathieu NOE
on 4 Sep 2025
just a side note
maybe this could also be of some interest : Symmetric Log Scale Plot - File Exchange - MATLAB Central
I'll come back later on your topic but I have to work a liitle bit for my boss right now
Andre Zeug
on 4 Sep 2025
-1.^(1/3) shows -1 as expected,
-1 is one of the cube roots of -1, but it's not the only one. What you want to compute there is one of the principal cube root:
principalCubeRoot = (-1).^(1/3)
or the real cube root:
realCubeRoot = nthroot(-1, 3)
or all the roots:
roots([1 0 0 1])
Andre Zeug
on 4 Sep 2025
Andre Zeug
on 4 Sep 2025
Is the first rather -(1.^(1/3))?
Correct. The .^ operator is at operator precedence level 2, while the unary minus operator - is at precedence level 4. [*]
When you write (-1).^(1/3) MATLAB computes the values inside each set of parentheses first (precedence level 1) then applies .^ to the results.
The () around the exponent are also necessary, as division is level 5. So this:
2.^1/3
is
(2.^1)/3
rather than
2.^(1/3) % or
nthroot(2, 3)
[*] Level 3 involves both power and unary minus, but is intended for things like this where unary minus is in the exponent:
2^-2 % 2 to the -2 power or 2^(-2)
Andre Zeug
on 4 Sep 2025
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)
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.
Categories
Find more on Just for fun in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!