let us suppose we have following code
function plot_test(x,y)
x_constucted=[ones(size(x)) x];
b = regress(y,x_constucted);
y_predicted=b(1)+b(2)*x;
scatter(x,y);
hold on
plot(x,y_predicted);
theString = sprintf('y = %.3f*x+%.3f ', b(2), b(1));
text(x(1), y_predicted(1), theString, 'FontSize', 8);
end
output of this equation is the following figure
my question is : how to align equation out of line? for instance on top left size? thanks in advance
If I understand you correctly, you want to move the printed equation out of the dots. Check out the text() function description. The first two values define the x and y position in your plot for the text.
x=1;
y=25;
To move it up, use the new variables in text(x,y,...). Hope that helps.
Some time ago I was looking for a solution for the same exact problem. As you may know, the legend command allows to specify a Location parameter and one of its many options is called best, described in the official Matlab documentation (here) as follows:
Inside axes where least conflict occurs with plot data
My workaround abuses this feature in order to find the best location to place a single text annotation inside the plot. The code below uses a build-in dataset since you didn't specify how your data looks like:
load carsmall;
x = [ones(size(Horsepower)) Horsepower];
y = MPG;
b = regress(y,x);
y_hat = b(1) + b(2) .* Horsepower;
scatter(Horsepower,y);
hold on;
plot(Horsepower,y_hat);
text_at_best(sprintf('y = %.3f*x+%.3f ',b(2),b(1)),'FontSize',12);
function h = text_at_best(txt,varargin)
l = legend(txt,[varargin{:}]);
t = annotation('textbox',varargin{:});
t.String = txt;
t.Position = l.Position;
t.LineStyle = 'None';
delete(l);
if nargout
h = t;
end
end
Here is the final result:
I don't know if this can fit your needs... but developing an algorithm for finding a non overlapping part of the plot in which to place a text looked like an overkill to me. Despite the text being quite far from the prediction line, it's still elegant, clear and comprehensible. The same goes with an even quicker workaround which consists in setting the regression equation as the plot title (blink blink).
Related
I am using Matlab to fit some data in 2 coordinates (x,y) with a poly1 curve.
The problem is that I can't find a way to make the fitting line longer.
I need it from (180, 930) to (191, 944), but instead Matlab just draw the fitting line near the data, which is between those two coordinates.
Is there some argument to the fit command (or some preferences in the cftool) that can help me out?
Moreover, I've tried the "Adjust axes limits" option in the cftool, but it didn't help at all.
I've searched through the already asked questions, but I haven't found anything related to this.
I'm new to this program, therefore I'm sorry if this is a stupid question
Thanks in advance,
Giovanni
EDIT:
The code for the first image is:
[FitUp,goodnessUP] = fit(AKaterMatrix1msDX(:,1),AKaterMatrix1msDX(:,2),'poly1')
[FitDown,goodnessDOWN] = fit(AKaterMatrix1msDX(:,1),AKaterMatrix1msDX(:,3),'poly1')
plot(FitUp,'b')
hold on
plot(FitDown,'b')
hold on
errorbar(AKaterMatrix1msDX(:,1),AKaterMatrix1msDX(:,2),AKaterMatrix1msDX(:,4),'--r')
hold on
errorbar(AKaterMatrix1msDX(:,1),AKaterMatrix1msDX(:,3),AKaterMatrix1msDX(:,4),'--r')
The code for the second is:
[FitUp,goodnessUP] = fit(AKaterMatrix1msDX(:,1),AKaterMatrix1msDX(:,2),'poly1')
[FitDown,goodnessDOWN] = fit(AKaterMatrix1msDX(:,1),AKaterMatrix1msDX(:,3),'poly1')
plot(FitDown,'b')
hold on
plot(FitUp,'b')
hold on
errorbar(AKaterMatrix1msDX(:,1),AKaterMatrix1msDX(:,2),AKaterMatrix1msDX(:,4),'--r')
hold on
errorbar(AKaterMatrix1msDX(:,1),AKaterMatrix1msDX(:,3),AKaterMatrix1msDX(:,4),'--r')
Here you can find the two fits, it appears that the first fit is not cropped, while the second after the hold on is:
https://docs.google.com/file/d/0B749BCu7mnZHaEhITUZ1YzdfVDA/edit?usp=sharing
https://docs.google.com/file/d/0B749BCu7mnZHeDVTOGRuSkktUmc/edit?usp=sharing
You just need to be careful when and how you set the hold. First make some dummy data
AKaterMatrix1msDX(:, 1) = 185:189;
AKaterMatrix1msDX(:, 2) = 2*rand(5, 1)+933;
AKaterMatrix1msDX(:, 3) = 2*rand(5, 1)+940;
AKaterMatrix1msDX(:, 4) = 2*rand(5, 1);
Next, and this is the key part, set the axis to be what you want and turn hold on
figure
axis([180, 191, 930, 944]);
hold on
This do exactly what you did
[FitUp,goodnessUP] = fit(AKaterMatrix1msDX(:,1),AKaterMatrix1msDX(:,2),'poly1')
[FitDown,goodnessDOWN] = fit(AKaterMatrix1msDX(:,1),AKaterMatrix1msDX(:,3),'poly1')
plot(FitUp,'b')
hold on
plot(FitDown,'b')
hold on
errorbar(AKaterMatrix1msDX(:,1),AKaterMatrix1msDX(:,2),AKaterMatrix1msDX(:,4),'--r')
hold on
errorbar(AKaterMatrix1msDX(:,1),AKaterMatrix1msDX(:,3),AKaterMatrix1msDX(:,4),'--r')
If you don't need a lot of fit statistics, polyfit followed by polyval can give you your fit:
X = AKaterMatrix1msDX(:,1);
Y = AKaterMatrix1msDX(:,2);
dY = AKaterMatrix1msDX(:,4);
[a,S] = polyfit(X,Y)
extraPlotRange = 10;
newX = linspace(min(X)-extraPlotRange,max(X)+extraPlotRange,100);
[fitY,delta] = polyval(a,newX);
plot(X,Y)
hold on
plot(newX,fitY)
plot(newX,fitY+delta,':b')
plot(newX,fitY-delta,':b')
errorbar(X,Y,dY,'--r')
hold off
This will not, unfortunately, give you the same goodness of fit statistics that you might need, only the confidence intervals of the fit.
The other option, if you want to stay with fit, would be to get the fit coefficients using coeffvalues. Those fit coefficients would be the same as you get from polyfit.
aUp = coeffvalues(FitUp);
aDown = coeffValues(FitDown);
fitYup = polyval(aUp,newX);
fitYdown = polyval(aDown,newX);
etc.
I have a dimension problem by using mesh-plot.The following example works good but I want to plot mesh(zz,TT,u(:,:,2,1)) instead of mesh(u(:,:,2,1)). At this case, the dimensions do not agree and matlab gives error. How can I order this dimension problem?
clear;
z=linspace(0,10,5);
T=linspace(0,20,50);
for j=1:length(T)-1
for i=1:length(z)
u(i,j,2,1)=z(i)*T(j)+10;
end
end
figure(1)
[zz,TT]=meshgrid(z,T);
mesh(u(:,:,2,1))
The code can be simplified as:
z = linspace(0,10,5);
T = linspace(0,20,50);
[zz,TT] = ndgrid(z, T(1:end-1));
uu = zz.*TT + 10;
%u(:,:,2,1) = uu;
mesh(zz, TT, uu)
I take out one less element from T, because thats how you filled the matrix u. Also note the difference between MESHGRID and NDGRID
Your question is not clear at all. Is this what you're looking for?
z=linspace(0,10,5);
T=linspace(0,20,50);
for j=1:length(T)
for i=1:length(z)
u(i,j)=z(i)*T(j)+10;
end
end
[TT, zz]=meshgrid(T, z);
I’m currently a Physics student and for several weeks have been compiling data related to ‘Quantum Entanglement’. I’ve now got to a point where I have to plot my data (which should resemble a cos² graph - and does) to a sort of “best fit” cos² graph. The lab script says the following:
A more precise determination of the visibility V (this is basically how 'clean' the data is) follows from the best fit to the measured data using the function:
f(b) = A/2[1-Vsin(b-b(center)/P)]
Granted this probably doesn’t mean much out of context, but essentially A is the amplitude, b is an angle and P is the periodicity. Hence this is also a “wave” like the experimental data I have found.
From this I understand, as previously mentioned, I am making a “best fit” curve. However, I have been told that this isn’t possible with Excel and that the best approach is Matlab.
I know intermediate JavaScript but do not know Matlab and was hoping for some direction.
Is there a tutorial I can read for this? Is it possible for someone to go through it with me? I really have no idea what it entails, so any feed back would be greatly appreciated.
Thanks a lot!
Initial steps
I guess we should begin by getting a representation in Matlab of the function that you're trying to model. A direct translation of your formula looks like this:
function y = targetfunction(A,V,P,bc,b)
y = (A/2) * (1 - V * sin((b-bc) / P));
end
Getting hold of the data
My next step is going to be to generate some data to work with (you'll use your own data, naturally). So here's a function that generates some noisy data. Notice that I've supplied some values for the parameters.
function [y b] = generateData(npoints,noise)
A = 2;
V = 1;
P = 0.7;
bc = 0;
b = 2 * pi * rand(npoints,1);
y = targetfunction(A,V,P,bc,b) + noise * randn(npoints,1);
end
The function rand generates random points on the interval [0,1], and I multiplied those by 2*pi to get points randomly on the interval [0, 2*pi]. I then applied the target function at those points, and added a bit of noise (the function randn generates normally distributed random variables).
Fitting parameters
The most complicated function is the one that fits a model to your data. For this I use the function fminunc, which does unconstrained minimization. The routine looks like this:
function [A V P bc] = bestfit(y,b)
x0(1) = 1; %# A
x0(2) = 1; %# V
x0(3) = 0.5; %# P
x0(4) = 0; %# bc
f = #(x) norm(y - targetfunction(x(1),x(2),x(3),x(4),b));
x = fminunc(f,x0);
A = x(1);
V = x(2);
P = x(3);
bc = x(4);
end
Let's go through line by line. First, I define the function f that I want to minimize. This isn't too hard. To minimize a function in Matlab, it needs to take a single vector as a parameter. Therefore we have to pack our four parameters into a vector, which I do in the first four lines. I used values that are close, but not the same, as the ones that I used to generate the data.
Then I define the function I want to minimize. It takes a single argument x, which it unpacks and feeds to the targetfunction, along with the points b in our dataset. Hopefully these are close to y. We measure how far they are from y by subtracting from y and applying the function norm, which squares every component, adds them up and takes the square root (i.e. it computes the root mean square error).
Then I call fminunc with our function to be minimized, and the initial guess for the parameters. This uses an internal routine to find the closest match for each of the parameters, and returns them in the vector x.
Finally, I unpack the parameters from the vector x.
Putting it all together
We now have all the components we need, so we just want one final function to tie them together. Here it is:
function master
%# Generate some data (you should read in your own data here)
[f b] = generateData(1000,1);
%# Find the best fitting parameters
[A V P bc] = bestfit(f,b);
%# Print them to the screen
fprintf('A = %f\n',A)
fprintf('V = %f\n',V)
fprintf('P = %f\n',P)
fprintf('bc = %f\n',bc)
%# Make plots of the data and the function we have fitted
plot(b,f,'.');
hold on
plot(sort(b),targetfunction(A,V,P,bc,sort(b)),'r','LineWidth',2)
end
If I run this function, I see this being printed to the screen:
>> master
Local minimum found.
Optimization completed because the size of the gradient is less than
the default value of the function tolerance.
A = 1.991727
V = 0.979819
P = 0.695265
bc = 0.067431
And the following plot appears:
That fit looks good enough to me. Let me know if you have any questions about anything I've done here.
I am a bit surprised as you mention f(a) and your function does not contain an a, but in general, suppose you want to plot f(x) = cos(x)^2
First determine for which values of x you want to make a plot, for example
xmin = 0;
stepsize = 1/100;
xmax = 6.5;
x = xmin:stepsize:xmax;
y = cos(x).^2;
plot(x,y)
However, note that this approach works just as well in excel, you just have to do some work to get your x values and function in the right cells.
I want to built a "travelling grid" MATLAB. Actually, I had to choose another MATLAB command instead of linspace to built my grid for any k. Is it possible with a MATLAB command?
for k=1:5
a=0;
b(k)=k.*3;
x=linspace(0,b(k),10);
y=linspace(0,30,10);
for z=1:length(x)
for t=1:length(y)
A(z,t,k)=x(z).*exp(-y(t));
end
end
end
Thanks for any help,
X = linspace(0,3,10);
XX(1,:,:) = bsxfun(#times,X,(1:5)')';
Y = exp(-linspace(0,30,10));
B = bsxfun(#times,Y',XX);
B = permute(B,[2,1,3]);
Your current code is working fine, so I'm not sure what the question is... Here is a slightly simpler implementation:
b = (1:5).*3;
A = zeros(10,10,5);
for k=1:5
[X,Y] = ndgrid(linspace(0,b(k),10), linspace(0,30,10));
A(:,:,k) = X.*exp(-Y);
end
If you also want the y-limits to change as well, the process is similar; you would have two loops and the result A being a 4D matrix
I have a scatter3 plot in which I use a vector C to define the colors of the different points. Here the color of the colormap is linearly mapped onto the numbers which are in C. I want to somehow find the RGB-values of each value inside my C vector. So I want a x by 3 matrix out of my C vector. Anybody knows if this is possible?
Best wishes,
Achim
Edit:
Thanks to #Aabaz I was able to solve the problem. Here is my solution:
colors_current = colormap;
color = [color zeros(length(color),2)];
stepw = floor(length(color)/length(colors_current));
colorsort = sortrows(color);
color_old = 0;
counter = 1;
for i = stepw:stepw:length(JAbs)
color_indices = find(color_old < color(:,1) & color(:,1) < color_sort(i));
if counter >= length(colors_current)
break;
end
for j=1:length(color_indices)
JAbs(color_indices(j),:) = colors_current(counter,:);
end
color_old = colorsort(i);
counter = counter + 1;
end
Not the most elegant way but it seems to work.
The function colormap used with no argument, returns the current axes colormap as an m by 3 matrix storing the RGB codes for each color. From there you can get to the RGB code for every element in your vector C.
UPDATE: I am sorry, I must have misread your question because I did not understand you were looking for an explicit way to get the rgb codes, just the connexion between the colormap and the rgb code. Anyway I see you found the solution yourself, well done. Did a quick try myself which I give you here :
n=10;
C=rand(n,1);
map=colormap(jet);
Cregspaced=(min(C):(max(C)-min(C))/(size(map,1)-1):max(C))';
Cmapindex=interp1(Cregspaced,(1:size(map,1))',C,'nearest');
Crgb=map(Cmapindex,:);
This should work, depending on how Matlab interpolates the index for the colormap. You can test it against your own solution to see if the results match.