Scientific notation at y-axis with "ax.YAxis.Exponent"

I want to change the notation of the log y-axis:
Here is an example code, which doesn't work:
y = [0.1 0.3 0.5 1];
figure(1),
plot(y)
yticks([0.1 0.5 1])
set(gca,'yscale','log')
ax = gca;
ax.YAxis.Exponent = 2
I found out that exponent notation doesn't work when yticks is used in conjunction with logarithmic scaling.
Any ideas???

 Accepted Answer

Well, here's a crude first pass...
expn=floor(log10(yticks));
mant=yticks./10.^(expn);
lbls=cellstr(num2str([mant;expn].','%d*10^{%d}'));
lbls=strrep(lbls,'1*','')
lbls =
3×1 cell array
{'10^{-1}' }
{'5*10^{-1}'}
{' 10^{0}' }
>>
Then
yticklabels(lbls)
produces
Salt to suit; no guarantees on how general will turn out to be...

13 Comments

Perfect! The elegant code works great! Many Thanks!
I hope I may ask one more question ...
How would the code have to be adapted if an identical exponent is to be used for all yticks and this is to be specified once for all above the graphic?
Here's an example:
Many, many thanks!!!
You would then set the exponent, expn arbitrarily and compute the mantissa. That would also then require find the number of cycles covered by the data range in order to compute the needed precision to be able to show sufficient significant digits.
The exponent would have to be written with text() constructed the same way as the above labels in the desired location.
So not that easy ...
Many thanks for the help!
You can arbitrarily change the exponent range on linear plots -- see how the values change when you do that for an arbitrary range of values on the y axis. That's what you've got to cope with. I suppose that would be one way to implement it -- set the axis to linear, set the exponent as you wish, then retrieve the xticklabels property.
hAx=gca; hY=hAx.YAxis;
hY.Scale='linear';
lbls=yticklabels;
hY.Scale='log';
hY.TickLabels=lbls;
hTxt=text(1,1.01,num2str(hY.Exponent,'10^{%d}'),'Color','k','VerticalAlignment','bottom');
does work to let the TMW code do the hard work in the linear scale mode that you can then write forcibly in log mode to match.
Thinking about this, now don't see why couldn't be done internally...so not sure precisely why TMW chose to neuter the log axis.
Now I run into the next error message:
Unrecognized property 'YScale' for class 'matlab.graphics.axis.decorator.NumericRuler'.
Error ...hY.YScale='linear';
Could the version be a problem? I use R2019a.
Oh, there's where I was trying to make the code here consistent -- in the command window I used a mishmash of the top-level axes handles and the YAxis handles --and just edited by hand.
When you use the YAxis or XAxis handles, then the X,Y prefixes for properties aren't needed...so it is either
hAx.YScale % overall axes handle -- needs direction prefix
or
hY.Scale % specific subaxes handle -- already knows direction, no prefix
Just look at all the properties of the handle; you'll get the correct spelling/capitalization with tab completion.
Many Thanks! What would be perfect now is if the exponent could be chosen freely. I tried to scale the plot and the yticks using the SCALE variable and to select the appropriate exponent using the if-condition ...
y = [0.1 0.3 0.5 1];
SCALE=100
figure(1),
plot(y/SCALE)
yticks([0.1 0.2 0.4 0.5 1]./SCALE)
hAx=gca; hY=hAx.YAxis;
hY.Scale='linear';
lbls=yticklabels;
hY.Scale='log';
hY.TickLabels=lbls;
if SCALE==0.001; hY.Exponent=-3;end
if SCALE==0.01; hY.Exponent=-2;end
if SCALE==0.1;hY.Exponent=-1;end
if SCALE==1;hY.Exponent=0;end
if SCALE==10;hY.Exponent=1;end
if SCALE==100;hY.Exponent=2;end
if SCALE==1000;hY.Exponent=3;end
hTxt=text(1,max(y)/SCALE+0.0,num2str(hY.Exponent,'×10^{%d}'),'Color','k','VerticalAlignment','bottom');
This is of course not very elegant ...
Are there better ways here?
Do you want ROUND() or FLOOR() here, Walter?
round. I did not want to assume that log10(0.001) was guaranteed to be exactly -3
Dear Walter and dpb,
thanks a lot for your support!

Sign in to comment.

More Answers (1)

I don't see a user-settable format to force the notation (although I didn't use Yair's getundoc to poke) with arbitrary tick values but
yticks(10.^(-1:1))
will trigger redrawing with the desired notation.
It's having intermediate tick labels that causes the switch.

2 Comments

Thanks for the answer, but I would like to set the individual ticks myself ...
Well, you can have one or the other, not both automagically.

Sign in to comment.

Asked:

on 11 Jun 2021

Commented:

on 14 Jun 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!