matlab, histogram how to find my data in the plot - matlab

I have my data in 2 vectors.
Then using [n,xout] = hist(x,y) returns vectors n and xout containing the frequency counts and the bin locations.
x are my real data and y the segment where I want to build my histogram.
Than I use bar(xout,n) to plot the histogram. In the end I am fitting this histogram with gaussian fit.
Now I would like to know where my real data (each point of vector x), are located in the histogram?
Can someone help me to figure out them?

[~, result] = min(abs(bsxfun(#minus, y(:), x(:).')));
This gives, for each value in x, the index of the closest element in y. So y(result) is the closest element in y for each x.
Example:
>> x = [0.4 1.6 5.3 4.2 3.1 7.8];
>> y = [0 2 4 6 8];
>> [~, result] = min(abs(bsxfun(#minus, y(:), x(:).')))
result =
1 2 4 3 3 5
>> y(result)
ans =
0 2 6 4 4 8

You want to use histc.
[binCounts, idx] = histc(x, y);
Then to find the bin in which a certain value of x is:
bin = idx(x == 0.4);
Just watch out since histc second input is not the centers like hist, but the end value of each bin. So you might need to change your y vector.

Related

How to plot mesh (with intensity profile on z) Nx3 matrix in Octave/Matlab?

I have got a data that are in a matrix of size N rows by 3 columns, each column corresponds to particular point in x, y and z axis. The data in that matrix have already been pre generated so my task is to plot it in a mesh as this is faster than creating the same plot with scatter function requiring 1M data points just to look similar.
The z will determine the corresponding color intensity as well as the valley and hills of the mesh.
Consider the example below:
A = [1 2 3; 1 3 2; 1 5 8; 1 2 6; 6 1 2];
mesh(A(:,1),A(:,2),A(:,3));
The attempt was nice, as I have already supplied appropriate x, y, and z for mesh function. However, I just get empty plot when I tested it. So, I am looking for help on how to plot mesh (with intensity profile on z) Nx3 matrix in Octave/Matlab?
Read about delaunay triangulation. YOu can make an unstructured mesh from your (x,y,z) data and then plot the mesh.
A = [1 2 3; 1 3 2; 1 5 8; 1 2 6; 6 1 2];
% mesh(A(:,1),A(:,2),A(:,3));
x = A(:,1) ;
y = A(:,2) ;
z = A(:,3) ;
dt = delaunayTriangulation(x,y) ;
triplot(dt) ;

Clampled cubic splines with flat extrapolation

I am trying to implement a clamped cubic spline with a zero slope (flat extrapolation) at the boundary knots, but I am unable to obtain the desired results.
For instance setting:
x = [3 4 7 9];
y = [2 1 2 0.5];
I can use the CSAPE function to obtain the piecewise polynomial
pp = csape(x,y,'variational');
Next, evaluating the pp in the range [0-10] yields,
xx = 0:0.1:10;
yy =ppval(pp,xx);
plot(xx,yy)
However, this method do not achieve a flat extrapolation outside the [3-9] range (i.e for x<3 all values for y should be 2, and for x>9 all values for y should be 0.5)
Is there any way to achieve the desired result?
Edit: Continuity at the boundary knot should be preserved
I don't think there's any need to use csape, you can just use spline. From the documentation for spline:
If Y is a vector that contains two more values than x has entries, the
first and last value in Y are used as the endslopes for the cubic
spline.
Also, spline allows you to obtain the interpolated yy values directly, so:
x = [3 4 7 9];
y = [2 1 2 0.5];
xx = 0:0.1:10;
yy = spline(x,[0 y 0], xx);
plot(xx,yy)
This gives me the plot below.
Looking at this, the slope is zero at the boundaries (x=3 and x=9), which is what we are asking of a 'clamped' spline with zero gradient at the boundaries. If you wish to have zero gradient beyond the boundaries, I would recommend just doing the following:
yy(xx<x(1)) = y(1);
yy(xx>x(length(x))) = y(length(y));
Giving:
Edit
This gives a continuous y function at the end-knots, but y' is not smooth at the end-knots. If you would like y' to be smooth you could pad your input arrays and use this as the input to your spline function. This would give you some oscillations as shown below, though, which may or may not be what you want.
% Spline on padded input arrays
x = [0 1 2 3 4 7 9 10 11 12];
y = [2 2 2 2 1 2 0.5 0.5 0.5 0.5];
yy = spline(x,y, xx);

create a Correct histogram

I have a range of data represented in the vector C
and have the data classes represented by the vector R
C = [1.71974522292994
1.91974522292994
2.03821656050955
2.13375796178344
2.16560509554140
2.22929936305733
2.35668789808917
2.38853503184713
2.54777070063694
2.61146496815287
2.70700636942675
2.73885350318471
2.83439490445860
2.96178343949045
3.02547770700637
3.31210191082803]
R = [1.71974522292994
2.03821104580359
2.35667686867724
2.67514269155088
2.99360851442453
3.31207433729818
3.63054016017183]
I need to do a histogram and a curve to overlap Standard Normal
z = histc(C,R); bar(R,z);
but the vector z that represents the frequency is not correct.
z = [2 4 4 4 1 1]'
on excell is so, and represents well the histogram
z = [1 1 4 4 4 1 1]'
you could suggest a solution using these two vectors?
Tnks
That's because Matlab's definition of histc:
n(k) counts the value x(i) if edges(k) <= x(i) < edges(k+1)
whereas Excel probably uses the more standard
edges(k) < x(i) <= edges(k+1)
So essentially you need to move the equal sign from below to above. You can get that either
By the trick of changing signs to both vectors and flipping the second (to keep it sorted):
>> z = histc(-C,-R(end:-1:1))
z =
1
1
4
4
4
1
1
Using the very powerful bsxfun function to directly compute the histogram with the equal sign above:
z = diff(sum(bsxfun(#le, C(:), [-inf R(:).'])));
I found it helpful to use this
z = histc(-C,-R);
the loop that I used for inside includes matrices with vectors of different length. I then filled the matrix with NaN
C and classe = [30x14] created by vectors with different lengths + NaN
[nr,nc] = size(C);
Freq = NaN*ones(nr,nc);
R = NaN*ones(nr,nc);
CC = NaN*ones(nr,nc);
I do not find a way in order to create the correct number of figures with the correct subplot.
In each figure there must be 4 subplot.
for k = 1:4
for j= 1 : nc;
R = classe(:,j);
CC = C(:,j);
FF = Freq(:,j);
R = R(~isnan(B)); % toglie i valori NaN
CC = CC(~isnan(CC));
R = sort(R,'descend');
CC = sort(C,'descend');
the line of Plot
FF = histc(-C,-R); % Calculate the J-th absolute frequencies
figure(k); <===?????
subplot(2,2,k) <=== ????????
bar(B,FF);
reassemble the matrices
if length(B)<nr
R(length(R)+1:nr)=NaN; % riempie la parte di colonna vuota
if length(CC)< nr;
C(length(CC)+1:nr)=NaN;
if length(FF)< nr;
FF(length(FF)+1:nr)=NaN;
end
end
end
classe(:,j)=R(:); % matrice classe
C(:,j)=CC(:) % matrice Elementi;
Freq(:,j)=FF(:); %Matrice Frequenze Assolute
end
the next steps concerns the in plotting of 3 figures. Each figure contains 4 subplot
I would also be able to superimpose on each histogram a standard normal curve ...
a tip?
tnks

Get list of Y's on linspace from X's and Y's arrays in Matlab

I have two arrays - X points and Y points. X array have some spaces (e. g. [0 1 2 6 7 8]), and Y array contains only values for that Xes. I've got that array as a local maxima from wavelet transform. I can plot it with plot(X,Y)
Now I want to get Y's on linspace - Y must contain values for any X from 0 to 8. I want to have the same plot plot(Y) as the previous plot(X, Y).
How can I do this?
It looks like you want to perform interpolation
xPts = [0 1 2 6 7 8];
yPts = ...
xPlot = 0:1:8;
yPlot = interp1(xPts,yPts,xPlot,'cubic')
plot(xPlot,yPlot)
Check the documentation for interp1 for the different interpolation schemes.
If there are repeated x-values, you can average the corresponding y-values
xPtsRep = [0 0 1 2 6 7 7 8]
yPtsRep = ...
[xPts,~,xIdx] = unique(xPtsRep);
yPts = accumarray(xIdx,yPtsRep,[],#mean);

Interpolation between components of a Matrix in MATLAB

In a project that I am doing I need to reach floating indexed elements of a matrix. That is to say for instance I want to reach the (16.25,1) th element of a matrix. That might seem odd at the first glance. However, by (16.25,1), I mean the interpolation between (16,1) and (17,1) with weights of .25 and .75 respectively.
Is there a built-in function for that?
Many thanks,
Safak
You can use interp2:
Z = randi(10,10); % 10 x 10 random matrix with integers from 1 to 10
Z(1:2,1:2)
%ans =
% 2 4
% 7 6
% use interp2 to interpolate at row 1.5, col 2
z = interp2(Z,1.5,2)
% z = 6.5000
You can use 2-D interpolation:
ZI = interp2(Z,XI,YI) assumes that X = 1:n and Y = 1:m, where [m,n] = size(Z)
where Z is your matrix, and XI & YI are your fractional indices.