Wavelenth vs Absorbance plot in MATLAB - matlab

I have a number of wavelengths and their corresponding absorbances.
First I entered the x and y values
x = [400 425 450 475 500 505 510 525];
y = [.24 .382 .486 .574 .608 .608 .602 .508];
To plot the points
plot(x, y, 'o')
Then I want to fit the data.
I'm not sure what degree of polynomial to choose, but since it's a plot of Wavelength vs Absorbtion, wont there already be a mathematical formula? Like how you know a plot of Kinetic energy vs Velocity will be degree 2 because KE = 1/2mv^2?

Alright so here is a solution that works fine with your data, using polyfit and polyval to evaluate a polynomial that passes through your data points.
In the doc for polyfit (here), it states that
In general, for n points, you can fit a polynomial of degree n-1 to
exactly pass through the points.
Since you have 8 data points, we can try using a polynomial of degree 7 and see what it givesL
clear
clc
x = [400 425 450 475 500 505 510 525];
y = [.24 .382 .486 .574 .608 .608 .602 .508];
%// Get polynomial coefficients to fit the data
p = polyfit(x,y,7)
%// Create polynomial to plot
fFit = polyval(p,x);
plot(x,y,'o')
hold on
plot(x,fFit,'r--')
hold off
axis([400 525 0 .7]);
legend({'Data points' 'Fitted curve'},'Location','NorthWest')
gives this:
So it does look to work very well! If we look at the coefficients given by polyfit:
p =
1.0e+05 *
Columns 1 through 6
0.0000 -0.0000 0.0000 -0.0000 0.0000 -0.0003
Columns 7 through 8
0.0401 -2.7206
Maybe the degree 7 was a bit overkill since the first 5 coefficients are 0 ( or about 0), but anyhow it fits very well!
Hope that helps!

Related

Color some samples of MATLAB figure with different color

I have a discrete signal x of length N traced in MATLAB using the command
stem(abs(x)); axis([0 N+6 0 4]);
The resulted figure is shown below:
My question I need only some values corresponding for example to index [7 10 11 12 15 18 48 50 52 60] to be colored with different color , let's say with red.
How can I do that into my figure ?
Using Multiple Plots by hold on and Matrix Indexing
You could possibly and alternatively place a plot on top of plot by using hold on. This does require an adjustment where you need a vector in this case Sample and Indices which specify the sample number/data point index. You can also use matrix indexing to get the amplitude/data points corresponding to the key point, Indicies.
%Vector relating to the sample/data point number%
Sample = linspace(1,70,70);
%Random test data%
X = randi([0,2],1,70);
stem(Sample,X);
hold on
%Key indices to change colour%
Key_Indices = [7 10 11 12 15 18 48 50 52 60];
%Matrix indexing to get values/amplitudes corresponding to key indices%
X_Prime = X(Key_Indices);
stem(Key_Indices,X_Prime,'r');
axis([0 70 0 3]);
hold off
Ran using MATLAB R2019b
This code makes just the circles red and not the stems
plot with selected red circles
%Vector relating to the sample/data point number
Sample = linspace(1,70,70);
%Random test data
X = randi([0,2],1,70);
stem(Sample,X);
%Key indices to change color
Key_Indices = [7 10 11 12 15 18 48 50 52 60];
line(Sample(Key_Indices), X(Key_Indices), 'linestyle', 'none', 'marker', 'o', 'color', 'r')
axis([0 70 0 3])
grid on

Matlab to calculate a spectral line parameter for each layer

I need to calculate a parameter defined as x,( this is defined in my code below) for the given spectral lines in each layer. My atmospheric profile has 10 layers. I know how to calculate x for just one layer. Then I get 5 values for x corresponding to each spectral line ( or wavelength) .
Suppose I want to do this for all 10 layers. Then my output should have 10 rows and 5 columns , size should be (10,5) , 10 represent number of the layer and 5 represent the spectral line. Any suggestion would be greatly appreciated
wl=[100 200 300 400 500]; %5 wavelengths, 5 spectral lines
br=[0.12 0.56 0.45 0.67 0.89]; % broadening parameter for each wavelength
p=[1 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 ]; % pressure for 10 layers
T=[101 102 103 104 105 106 107 108 109 110]; % temperature for 10 layers
%suppose I want to caculate a parameter, x for all the layers
% x is defined as,( wavelength*br*T)/p
%when I do the calculation for the first layer,I have to consider all the
%wavelengths , all the broadening parameters and only the first value of
%pressure and only the first value of temperature
for i=1:5;
x(i)= (wl(i)*br(i)*T(1))/p(1);
end
% x is the x parameter for all the wavelengths in the first layer
%Now I want to calculate the x parameter for all the wavelengths in all 10
%layers
%my output should have 10 rows for 10 layers and 5 columns , size= (10,5)
you don't need loops for this case
>> (T./p)'*(wl.*br)
ans =
1.0e+05 *
0.0121 0.1131 0.1364 0.2707 0.4495
0.0136 0.1269 0.1530 0.3037 0.5043
0.0155 0.1442 0.1738 0.3451 0.5729
0.0178 0.1664 0.2006 0.3982 0.6611
0.0210 0.1960 0.2362 0.4690 0.7788
0.0254 0.2374 0.2862 0.5682 0.9434
0.0321 0.2996 0.3611 0.7169 1.1904
0.0432 0.4032 0.4860 0.9648 1.6020
0.0654 0.6104 0.7358 1.4606 2.4253
0.1320 1.2320 1.4850 2.9480 4.8950

polyfit does not seem to fit data very well in matlab

I am using polyfit in matlab to plot a straight line of best fit through points. However, the best fit line is not as I would expect - the line does not look like it fits the data very well... does it? Here's my code, any help with improving this would be great. (Note, the axis limits I have set are important).
x = [0 1 10 5 1 1.5];
y = [-14 -18 -22 -26 -30 -34];
scatter(x,y)
hold on
p = polyfit(x,y,1);
f = polyval(p,x);
plot(x,f,'-r','linewidth',1.2)
ylim([-35 -10])
xlim([-30 30])
Your fit looks proper to me, but this might be what you're looking for instead
x = [0 1 10 5 1 1.5];
y = [-14 -18 -22 -26 -30 -34];
scatter(x,y)
hold on
p = polyfit(y,x,1);
f = polyval(p,y);
plot(f,y,'-r','linewidth',1.2)
ylim([-35 -10])
xlim([-30 30])
Here's a total least squares solution
data=[x(:), y(:)];
c=mean(data);
data=bsxfun(#minus,data,c);
[~,~,v]=svd(data);
d=v(:,end);
k=dot(d,c);
ezplot(#(x,y) x*d(1)+ y*d(2)-k, [-30 30 -35 -10])

How to calculate the slope in percentage of linearly fitted data in Matlab

I hope someone can help me.
Lets say I have the following two vectors
t = [1 2 3 4 5];
m = [10 8 6 4 2];
plot(t,m)
And I want to find the slope of the linear fit (1. degree)
so I write:
polyfit(t,m,1)
I then obtain the following answer:
ans =
-2.0000 12.0000
Meaning that y = -2x + 12
How do I re-calculate the coefficient to a percentage slope?
The reason I am interested in this is that I want to discard all data that has a slope < 80% (and proceed with data with slope coefficients between 80% and 100%).
Assuming that you define percentage slope by the formula given in #2 of the Nopmenclature section on the Wikipedia Grade page, 100 * dy / dx, your percentage slope is just the coefficient of x^1, multiplied by 100. You can do a test to check for slopes < 80% as follows:
t = [1 2 3 4 5];
m = [10 8 6 4 2];
p = polyfit(t,m,1);
g = p(1) * 100;
if g > 80 && g < 100
% Do what you need to do...
end

using matlab surf functions with x size 11 and y size 6

I am trying to use matlab for calculating the approximation of a function using the composite trapezoidal rule, and then displaying the function and approximation using a surf function and a bar3 function. the thing is is that when I try plot the function surf(x,y,Z) I receive and error saying dimension's mismatch.
my question is how would I get the surf function to plot the 3D graph when my x,y and z arrays differ in size.
I've tried to create zeros functions of the the x and y array's of the same size and then adding my values to each, then NaN'ing the extra 0's, but as u see each of my arrays start with 0's therefore NaN'ing where i find a zero in my arrays will effect my graph plot. and plus i still get the same error "dimensions mismatch" so i supposed thats because my Z array is bigger than my x and y.
Any help would be appreciated.
code for my x and y are:
`
x = linspace(a,b,h); %h being 11 and breaks up the difference because datapoints a and b into h number of sub intervals
y = linspace(c,d,k); %k being 6 and breaks up the difference because data points c and d into k number of sub intervals
Z = zeros(h,k);
for i = 1:1:h
for j = 1:1:k
Z(i,j) = f(x(i),y(j));
end
end
surf(x,y,Z);
`
x
0 0.3000 0.6000 0.9000 1.2000 1.5000 1.8000 2.1000 2.4000 2.7000 3.0000
y
0 0.6286 1.2571 1.8857 2.5143 3.1429
Z
0 0 0 0 0 0
0 0.1764 0.2854 0.2852 0.1761 -0.0004
0 0.3528 0.5707 0.5705 0.3522 -0.0008
0 0.5292 0.8561 0.8557 0.5283 -0.0011
0 0.7056 1.1415 1.1410 0.7044 -0.0015
0 0.8820 1.4268 1.4262 0.8804 -0.0019
0 1.0584 1.7122 1.7115 1.0565 -0.0023
0 1.2348 1.9975 1.9967 1.2326 -0.0027
0 1.4112 2.2829 2.2820 1.4087 -0.0030
0 1.5876 2.5683 2.5672 1.5848 -0.0034
0 1.7640 2.8536 2.8525 1.7609 -0.0038
Error using surf (line 75)
Data dimensions must agree.
Error in CompositeTrapazoidal>btnSolve_Callback (line 167)
surf(x,y,Z);
Try surf(x,y,Z'); (because x's length should match the Z's column count)