Convert from linear to log scale and back again
Show older comments
I have include some example data.
%fit curve
[xData, yData] = prepareCurveData(log10(plot_data.xdata), plot_data.ydata);
ft = fittype( 'poly1' );
[fitresult, gof] = fit( xData, yData, ft ); %fit model to data
ci=confint(fitresult,0.95);
sp1=plot(fitresult,xData,yData,'ob'); %plot
I have distance on the x-axis, and sound pressure level on the y-axis. The distances are originally in metres, but when I fit a best fit line, the equation I use needs them to be logged. My issue is that I want to convert the x-axis back to metres so it's in a readable format. In addition, I'd like this to be on a logarithmic scale.
I tried the following:
xticklabels({'','','100','','','','','1000'}) %re-label x ticks in metres
set(gca,'XScale','log')
but the x-axis doesn't appear to be logged at all when I do this and the 1000m value disappears when I set the scale to log.
Answers (1)
Jon
on 23 Nov 2021
0 votes
I think you can get what you want using MATLAB's semilogx function
21 Comments
Louise Wilson
on 23 Nov 2021
Edited: Louise Wilson
on 23 Nov 2021
Jon
on 23 Nov 2021
I don't have the curve fitting toolbox so I can't try your code exactly. It may be (although it would be surprising) that the curve fitting toolbox doesn't provide the option for making semilog plots, and in particular I'm not sure if MATLAB's semilogx will take a fitobject as an argument. You can always evaluate your fit object at the values of x of interest and put the result into an ordinary matlab vector and then use the semilogx function on that. Maybe someone who has the curve fitting toolbox can suggest a cleaner approach.
Jon
on 23 Nov 2021
regarding lines versus symbols you have to specify the linespec to use symbolds e.g.
semilogx(xData,yData,'o')
Jon
on 23 Nov 2021
assuming you can make a vector, let's call it yfit, with your fitted values (by evaluating your fit object at the points in xData) you could plot the original data and the fit using
semilogx(xData,yData,'o',xData,yfit,'-')
Louise Wilson
on 23 Nov 2021
Jon
on 23 Nov 2021
I'm not sure what you mean by a readable unit. Please attach a screenshot of your plot so I can see how it looks.
Jon
on 23 Nov 2021
So I think you are saying that you do not want to have 10^0 10^1 10^2 ... but instead 1,10, 100, ...
You can use this trick from https://www.mathworks.com/matlabcentral/answers/95023-how-do-i-change-the-x-axis-label-on-a-semilogx-plot-from-exponential-to-normal-format-in-matlab
semilogx(xData,yData,'o',xData,yfit,'-')
New_XTickLabel = get(gca,'xtick');
set(gca,'XTickLabel',New_XTickLabel);
Louise Wilson
on 23 Nov 2021
Edited: Louise Wilson
on 23 Nov 2021
Jon
on 23 Nov 2021
You get the error because fitresult is a curve fit obj not a vector of numeric values as semilogx expects. So you have to first calculate a vector of numeric values by evaluating your fit function at each x data point.
Unfortunately I don't have the curve fitting toolbox so I can't test this first to see if it works but I think this should be close:
yfit = fitresult(xData) % evaluate the fit function at the x data points
semilogx(xData,yData,'o',xData,yfit,'-')
New_XTickLabel = get(gca,'xtick');
set(gca,'XTickLabel',New_XTickLabel);
Louise Wilson
on 23 Nov 2021
Edited: Louise Wilson
on 23 Nov 2021
Jon
on 24 Nov 2021
I'm not clear about which code "works". Did you try the approach I suggested above calculating yfit and using semilogx? What did the plot look like from those lines of code? I'm pretty sure the plot you show is not the result of using semilogx
Louise Wilson
on 24 Nov 2021
Jon
on 24 Nov 2021
Did you run exactly this code:
yfit = fitresult(xData) % evaluate the fit function at the x data points
semilogx(xData,yData,'o',xData,yfit,'-')
New_XTickLabel = get(gca,'xtick');
set(gca,'XTickLabel',New_XTickLabel);
I tried semilogx a number of times, it always gives me the log spacing that you are looking for. Maybe check to see if that plot is really the result of semilogx
Louise Wilson
on 24 Nov 2021
Jon
on 24 Nov 2021
This is what you provided as plot3.png, it has linear spacing

Jon
on 24 Nov 2021
Once again, here is a simple example generating a plot with log spacing and units of the form 10,100,... rather than 10^1, 10^2
x = 1:1000
yfit = x.^2
semilogx(x,yfit),
get(gca,'xtick')
set(gca,'XTickLabel',New_XTickLabel)
I think you should be able to get something similar.

Louise Wilson
on 24 Nov 2021
Jon
on 24 Nov 2021
As shown in the code I gave you, you evaluate to apply the output of fit at specific x values and assign them to an ordinary numeric vector use
yfit = fitresult(xData)
after that it is just an ordinary use of semilogx.
If you want to evaluate it at many x values in the range of interest you could use
xfit = linspace(min(xData),max(xData),1000)
yfit = fitresult(xfit)
semilogx(xData,yData,'o',xfit,yfit,'-')
New_XTickLabel = get(gca,'xtick');
set(gca,'XTickLabel',New_XTickLabel);
What part of the code isn't working for you?
Louise Wilson
on 24 Nov 2021
Sorry, I don't have the curve fitting toolbox, so I can't try running your exact code to see if I can replicate the problem. I'm pretty sure the plot3.png that you attached is not the output from your code above, maybe some confustion in the files or something like that. For me using semilogx always produces a log spaced output and your plot3.png has a linear one. As I showed you a few post ago, when I make a ordinary numerical vectors xData, and yfit, and and run the last three lines of code above I get a log spaced x axis with labels 10,100,...
Just to be clear I will post the example again here.
x = 1:1000
yfit = x.^2
semilogx(x,yfit),
get(gca,'xtick')
set(gca,'XTickLabel',New_XTickLabel)
Which produces

Is this the kind of plot you are hoping to get? When you run the above code do you get the same plot I show above
If so, I can't really explain why you don't get the same result with your code and I guess I can't offer you any more help. If the example above, with made up data gives the plot you want, and when you assign the output using fitresult(xData) it doesn't work, then either there is some slight but important difference between our two codes, or maybe there is some aspect of using the curve fit toolbox that I am not aware of, but I'm mystified and frustrated I couldn't get this working for you. Sorry, I hope you can figure it out soon.
Louise Wilson
on 25 Nov 2021
Categories
Find more on Time Series Events 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!