plot scree plot in matlab - matlab

How to plot scree plot in matlab using Singular Value Decomposition(SVD)?
I have already calculate first and second factor and loadings.
[U,S,V] = svd(x);
ls1 = S(1,1)*V(:,1)';
ls2 = S(2,2)*V(:,2)';

Related

Cross validation and ROC curve using Matlab: how plot mean ROC curve?

I am using k-fold cross validation with k = 10. Thus, I have 10 ROC curves.
I would like to average between the curves. I can't just average the values ​​on the Y axes (using perfcurve) because the vectors returned are not the same size.
[X1,Y1,T1,AUC1] = perfcurve(t_test(1),resp(1),1);
.
.
.
[X10,Y10,T10,AUC10] = perfcurve(t_test(10),resp(10),1);
How to solve this? How can I plot the average curve of the 10 ROC curves?
So, you have k curves with different number of points, all bound in [0..1] interval in both dimensions. First, you need to calculate interpolated values for each curve at specified query points. Now you have new curves with fixed number of points and can compute their mean. The interp1 function will do the interpolation part.
%% generating sample data
k = 10;
X = cell(k, 1);
Y = cell(k, 1);
hold on;
for i=1:k
n = 10+randi(10);
X{i} = sort([0 1 rand(1, n)]);
Y{i} = sort([0 1 rand(1, n)].^.5);
end
%% Calculating interpolations
% location of query points
X2 = linspace(0, 1, 50);
n = numel(X2);
% initializing values for different curves at different query points
Y2 = zeros(k, n);
for i=1:k
% finding interpolated values for i-th curve
Y2(i, :) = interp1(X{i}, Y{i}, X2);
end
% finding the mean
meanY = mean(Y2, 1);
Notice that different interpolation methods can affect your results. For example, the ROC plot data are kind of stairs data. To find the exact values on such curves, you should use the Previous Neighbor Interpolation method, instead of the Linear Interpolation which is the default method of interp1:
Y2(i, :) = interp1(X{i}, Y{i}, X2); % linear
Y3(i, :) = interp1(X{i}, Y{i}, X2, 'previous');
This is how it affects the final results:
I solved it using Matlab's perfcurve. For that, I had to pass as a parameter a list of vectors (size vectors 1xn) for "label" and "scores". Thus, the perfcurve function already understands as a set of resolutions made using k-fold and returns the average ROC curve and its confidence interval, in addition to the AUC and its confidence interval.
[X1,Y1,T1,AUC1] = perfcurve(t_test_list,resp_list,1);
t_test and resp they are lists of size 1xk (k is the number of folds / k-fold) and each element of the lists is a 1xn vector with scores and labels.
resp = nnet(x_test(i));
t_test_act = t_test(i);
resp has 2xn format (n is the number of predicted samples). There are two classes.
t_test_act contains the labels of the current set of tests, it has formed 2xn and is composed of 0 and 1 (each column has a 1 and a 0, indicating the true class of the sample).
resp_list{i} = resp(1,:) %(scores)
t_test_list{i} = t_test_act(1,:) %(labels)
[X1,Y1,T1,AUC1] = perfcurve(t_test_list,resp_list,1);

Plot correlation values corresponding to a transformed meshgrided (X,Y) coordinates

I have a matrix 3x121 that contains (x,y, correlation value),
First, I do a meshgrid of (x,y), then a transformation of (x,y) meshgrided into new coordinates (x',y') with x'=y/x and y'=1/x^2*y.
I have to plot the correlation according to the new coordinates (x',y') showed in the attached screen shot.
![1]: https://imgur.com/jL86sCr "correlation"
Here is the code that I used:
load('correlation_xy_0.mat');
x = double(corr_xy(1,:,:));
y = double(corr_xy(2,:,:));
correlation = double(corr_xy(3,:,:));
[X,Y] = meshgrid(x,y);
Xp = Y./X;
Yp = 1./(X.^2 .*Y);
plot(Xp,Yp,'Color',correlation)
Thanks
You need to define a colormap and provide RBG values. You also need to do this for each point independently, you can not do it in one line
cmap=parula; % choose a colormap
correlation=reshape(correlation,size(X));
hold on
for ii=1:size(x,1)
for jj=1:size(x,1)
plot(Xp(ii,jj),Yp(ii,jj),'x','color',cmap(floor(correlation(ii,jj)*size(cmap,1)+1),:) )
end
end

In Matlab, how to draw lines from the curve to specific xaxis position?

I have a spectral data (1000 variables on xaxis, and peak intensities as y) and a list of peaks of interest at various specific x locations (a matrix called Peak) which I obtained from a function I made. Here, I would like to draw a line from the maximum value of each peaks to the xaxis - or, eventually, place a vertical arrow above each peaks but I read it is quite troublesome, so just a vertical line is welcome. However, using the following code, I get "Error using line Value must be a vector of numeric type". Any thoughts?
X = spectra;
[Peak,intensity]=PeakDetection(X);
nrow = length(Peak);
Peak2=Peak; % to put inside the real xaxis value
plot(xaxis,X);
hold on
for i = 1 : nbrow
Peak2(:,i) = round(xaxis(:,i)); % to get the real xaxis value and round it
xline = Peak2(:,i);
line('XData',xline,'YData',X,'Color','red','LineWidth',2);
end
hold off
Simple annotation:
Here is a simple way to annotate the peaks:
plot(x,y,x_peak,y_peak+0.1,'v','MarkerFaceColor','r');
where x and y is your data, and x_peak and y_peak is the coordinates of the peaks you want to annotate. The add of 0.1 is just for a better placing of the annotation and should be calibrated for your data.
For example (with some arbitrary data):
x = 1:1000;
y = sin(0.01*x).*cos(0.05*x);
[y_peak,x_peak] = PeakDetection(y); % this is just a sketch based on your code...
plot(x,y,x_peak,y_peak+0.1,'v','MarkerFaceColor','r');
the result:
Line annotation:
This is just a little bit more complicated because we need 4 values for each line. Again, assuming x_peak and y_peak as before:
plot(x,y);
hold on
ax = gca;
ymin = ax.YLim(1);
plot([x_peak;x_peak],[ymin*ones(1,numel(y_peak));y_peak],'r')
% you could write instead:
% line([x_peak;x_peak],[ymin*ones(1,numel(y_peak));y_peak],'Color','r')
% but I prefer the PLOT function.
hold off
and the result:
Arrow annotation:
If you really want those arrows, then you need to first convert the peak location to the normalized figure units. Here how to do that:
plot(x,y);
ylim([-1.5 1.5]) % only for a better look of the arrows
peaks = [x_peak.' y_peak.'];
ax = gca;
% This prat converts the axis unites to the figure normalized unites
% AX is a handle to the figure
% PEAKS is a n-by-2 matrix, where the first column is the x values and the
% second is the y values
pos = ax.Position;
% NORMPEAKS is a matrix in the same size of PEAKS, but with all the values
% converted to normalized units
normpx = pos(3)*((peaks(:,1)-ax.XLim(1))./range(ax.XLim))+ pos(1);
normpy = pos(4)*((peaks(:,2)-ax.YLim(1))./range(ax.YLim))+ pos(2);
normpeaks = [normpx normpy];
for k = 1:size(normpeaks,1)
annotation('arrow',[normpeaks(k,1) normpeaks(k,1)],...
[normpeaks(k,2)+0.1 normpeaks(k,2)],...
'Color','red','LineWidth',2)
end
and the result:

Matlab - How can I get the expression of the level curves of a function?

I would like to obtain the level curves of a given function z=f(x,y) without using the countours function in the Matlab environment.
By letting Z equal to some constant 'c' we get a single level curve. I would like to obtain an expression of the resulting function of the form y=f(x) to be able to study other properties of it.
Basic: Example 1: Easy game
Let's consider the problem of plotting level curves of z=-x^2-y^2+100 for x,y:-10;10 and z=1.
[X,Y] = meshgrid(-10:.1:10);
Z = -X.^2+-(Y).^2+100;
surf(X,Y,Z)
we obtain the following figure:
The countour function gives me what I was looking for:
h=[1,1]
contour(X,Y,Z,h)
I can get the same result by solving the equation with respect to x
syms x y;
soly = solve(1==-x.^2-y^2+100, y)
t=soly(1)
x=-10:0.1:10;
figure;
plot(x,(99-x.^2).^(1/2));
hold on
plot(x,-(99-x.^2).^(1/2));
soly =
(99 - x^2)^(1/2)
-(99 - x^2)^(1/2)
The Problem: Example 2
Let's consider the following 3D function.
This function is the sum of guassians with random centers, variances and peaks. You can get it with the following code:
%% Random Radial Basis functions in space
disp('3D case with random path - 10 rbf:');
N = 10 % number of random functions
stepMesh = 0.1;
Z = zeros((XMax-XMin)/stepMesh+1,(XMax-XMin)/stepMesh+1);
[X,Y] = meshgrid(XMin:stepMesh:XMax);
% random variance in [a;b] = [0.3;1.5]
variances = 0.3 + (1.5-0.3).*rand(N,1);
% random amplitude [0.1;1]
amplitudes = 0.1 + (1-0.1).*rand(N,1);
% Random Xcenters in [-XMin;xMax]
Xcenters = XMin+ (XMax-XMin).*rand(N,1);
Ycenters = YMin+ (YMax-YMin).*rand(N,1);
esp=zeros(N,1);
esp=1./(2*(variances).^2);
for i=1:1:N
disp('step:')
disp(i)
Xci=Xcenters(i,1)*ones((XMax-XMin)/stepMesh+1,((XMax-XMin)/stepMesh+1)*2);
Yci=Ycenters(i,1)*ones((YMax-YMin)/stepMesh+1,((YMax-YMin)/stepMesh+1)*2);
disp('Radial Basis Function: [amplitude,variance,center]');
disp(amplitudes(i,1))
disp(variances(i,1))
disp(Xcenters(i,1))
disp(Ycenters(i,1))
Z = Z + 1*exp(-((X-Xci(:,1:((XMax-XMin)/stepMesh+1))).^2+(Y-Yci(:,((XMax-XMin)/stepMesh+2):((YMax-YMin)/stepMesh+1)*2)).^2)*esp(i,1).^2);
end
surf(X,Y,Z)
The countour3 function draws a contour plot of matrix Z in a 3-D view, which is really nice, but it doesn't give me the expression of these functions in 2D.
figure;
contour3(X,Y,Z);
grid on
box on
view([130,30])
xlabel('x-axis')
ylabel('y-axis')
zlabel('z-axis')
The Question:
How can I get an explicit expression of the level curves of the second example?

Calculate tangent for measurement data

I have some measurement data which I want to plot. I plot only the points and used the Curve Fitting Toolbox to generate a regression function which I plot.
Now I want to calculate and plot the tangent on a certain point. How can I do that using Matlab?
If you have point and function, you can calculate the tangent which is:
let say the desired index is 5. y = mx+n
m = (diff(y) ./ diff(y)) (5)
n = y(5)-x(5)*m
and then
hold on
plot (x, (m*x+n));
links:
http://www.kxcad.net/cae_MATLAB/toolbox/curvefit/bqxox7w.html
http://www.weizmann.ac.il/matlab/toolbox/curvefit/cfit.html
http://www.mathworks.com/matlabcentral/newsreader/view_thread/170100
With the help of #0x90 I got the solution:
zerocross = ceil(fzero(fit, 1000));
x_tan = zerocross-101:0.1:zerocross+100;
y_tan = feval(fit, x_tan);
k = (diff(y_tan) ./ diff(x_tan));
k = k(length(k) / 2); % get zero point
d = y_tan(5)-x_tan(5)*k;
plot (x_tan, (k*x_tan+d));