CDF plot doesn't start from zero - matlab

I've tried to plot cdfcurves of my data by calling cdfplot(x) function. Here is part of my code:
figure;
for i=1:length(num_curves)
h = cdfplot(10*log10(plot_vec1(:,i)));
set(h,'Linewidth',2,'Color',cc(i,:),'Linestyle','-');
hold on
%set(color, cc(i,:));
end
Unfortunately the result I get is very confusing.
Yellow and purple curves are starting from nonzero value, but CDF curve should always start from zero!
Can anyone give me some suggestions? I've tried to plot yellow curve by itself, but it is still 'biased'.
Thank you for help!

The problem is that your data plot_vec1 contains zeros. Those zeros are transformed to -inf when you transform to dB with 10*log10(). Then cdfplot sees that the minimum finite value (about -67 in your yellow curve) has many samples (with value -inf) below it. That's why it gives a non-zero accumated probability there.
For example, compare these two figures
Normal case, all values are finite:
cdfplot([1 2 3 4 5 6])
Some values are -inf:
cdfplot([-inf -inf 3 4 5 6])
Here the minimum finite value, which is 3, has a 0.33 cumulative probability shown on the vertical axis. That's because 2 of the 6 samples are - inf and are thus below 3:
Possible workarounds: remove those zeros before applying the logarithm, or replace the resulting -inf by a very small value in dB, such as -100.

Related

Matlab `quantile` doesn't interpolate between sample values on ECDF?

According to Matlab's help, quantile interpolates linearly between points on the empirical cumulative distribution function (ECDF). Importantly, the points interpolated between are the mid-points of the risers at each step. I'm finding the actual behaviour to be significantly different. Here is my example, the ECDF, and a line segment to show the interpolation:
y= [ 1 2 5 5 5 5 5 5 9 10 ]
ecdf(y)
grid on
set(get(gca,'Children'),'LineWidth',2)
hold on
% Line segment for interpolation
x2points=[2;5]; y2points=[0.15;0.5];
plot(x2points,y2points)
From the interpolation line segment, we would expect the quantile for F(x)=0.3 to be around x=3.3, but instead, it is x=5.
yInterior=0.3 % Value to get `x` for
xInterior=interp1(y2points,x2points,yInterior) % ans = 3.2857
xInterior=quantile(y,yInterior) % ans x=5
Is there another piece of documentation elsewhere that I'm missing which explains this difference?
Am I the only one seeing this?
I'm using Matlab 2015b.

how do you visualize a matrix whose elements are vectors in MATLAB?

I have generated a 3 x 2 x 25 matrix A in MATLAB.
A(1,2,1) = 5 means method 1, type 2, trial 1 has a count value of 5.
A(3,1,2) = 7 means method 3, type 1, trial 2 has a count value of 7.
Basically, there are 25 count values for each (method, type) pair.
In the past, I have used "histogram" MATLAB function to visualize a 2-D frequency plot and I know I can use it here like so:
histogram(A(3,1,:))
But if I use histogram I would have to plot all 6 like:
histogram(A(1,1,:))
histogram(A(1,2,:))
histogram(A(2,1,:))
histogram(A(2,2,:))
histogram(A(3,1,:))
histogram(A(3,2,:))
But I was wondering if there is a way to all 6 plots in a 3-dimensional histogram ?
You want 4 dimensions of information on a 3 dimensional plot. the only good way to get a 4th dimension of information would probably be color and that's going to be a mess with 6 plots. You're better off separating the plots into different graphs.
From what you're describing the second dimension only has 2 states. Would it make sense in your case to have 2 3d plots with this dimension being split across graphs/colors?

Using MATLAB, is there a way to get a 2D visualisation of data points that are in 6D space?

Part of an assignment of mine is to provide a 2D visualisation (plots) of some of my data points that are stored in a matrix. I'm slightly confused because the data is actually in 6D space (i.e. each row has 6 columns like 0 1 0 8 8 2).
Is there something I'm missing or does this genuinely not make sense? Is this something MATLAB can do?
Edit: Is something like this possible?
Though I wouldn't consider it visualizing 6D data, you can get the linked plot with a simple call to plot:
A = rand(6);
x = 1:6;
plot(x,A'); % Transpose A to plot rows since it's square, see plot documentation
Which produces the following:
From the documentation:
If one of X or Y is a vector and the other is a matrix, then the
matrix must have dimensions such that one of its dimensions equals the
vector length. If the number of matrix rows equals the vector length,
then the plot function plots each matrix column versus the vector. If
the number of matrix columns equals the vector length, then the
function plots each matrix row versus the vector. If the matrix is
square, then the function plots each column versus the vector.
Simply use:
surf(2Dmatrix)
You can read more here: http://uk.mathworks.com/help/matlab/ref/surf.html
If your matrix is 2D image, simply use
figure; imshow(2Dmatrix, [])
If you leave the square bracket empty, the limit will be automatic. When the figure is displayed you can change it to different colormap by Edit > Colormap.

3-D Plotting with MATLAB for Galton's Skewness and Moor's Kurtosis

I know there are many plotting documents for Matlab online and I am pretty sure that it has been asked many times. I aplogize in advance for any inconvenience.
I am dealing with a new distribution and I need to draw 3D plot for different values of parameters (I can do it with Excel or any other programs, however, since my other graphs is drawn with MATLAB, and I need to put this 3D in Matlab, too, to publish it as an article). I calculated the result using MATLAB loops, however, plotting gives me the hardest time. I had no other choice but to ask for your assistance. I have these equations for different alphas and betas with a constant sigma and calculate Galton's Skewness and Moor's Kurtosis given with the last two equations.
median=sqrt(2*(sigma^2)*beta*gammaincinv(0.5,alpha));
q1=sqrt(2*(sigma^2)*beta*gammaincinv((6/8),alpha));
q3=sqrt(2*(sigma^2)*beta*gammaincinv((2/8),alpha));
q4=sqrt(2*(sigma^2)*beta*gammaincinv((7/8),alpha));
q5=sqrt(2*(sigma^2)*beta*gammaincinv((5/8),alpha));
q6=sqrt(2*(sigma^2)*beta*gammaincinv((3/8),alpha));
q7=sqrt(2*(sigma^2)*beta*gammaincinv((1/8),alpha));
galtonskewness=(q1-2*median+q3)/(q1-q3);
moorskurtosis=(q4-q5+q6-q7)/(q1-q3);
Let's assume that,
sigma=1
beta=[0.1 0.2 0.5 1 2 5];
alpha=[0.1 0.2 0.5 1 2 5];
I have used mesh(X,Y,Z) for the same range of alphas and betas with the same increment but I take the error "these values cannot be complex". I just want to draw something like the one below.
It must be something easy that I am missing out, but I do not understand where the mistake is. I appreciate any help. Thank you!
I ran the above code for a 2D mesh of points for alpha and beta between 0.1 and 5 for both dimensions and I got results for both.
I suspect it's due to your alpha and beta declaration. You are only providing a few points, and if you try to use mesh, it won't get good results. Therefore, define a meshgrid of points for both alpha and beta, then vectorize your MATLAB code to produce the kurotsis and skewness curves. Only under certain situations should you use for loops. In general, you should avoid using them whenever possible.
How meshgrid works is that given a range of X and Y values, it will produce two (or three if you want 3D co-ordinates) arrays where each location in each array gives you the spatial co-ordinate at that particular location. Therefore, if we did something like:
[X,Y] = meshgrid(1:3, 1:3);
This is what we get:
X =
1 2 3
1 2 3
1 2 3
Y =
1 1 1
2 2 2
3 3 3
Notice that in a 2D grid, for the top-left corner, (x,y) = (1,1), and so for the corresponding location in X, we get 1 and Y we get 1. If you do the same logic for any other position in the 2D grid, you simply look at the X and Y values in each array and it will tell you what the component is for each dimension.
As such, instead of looping through all possible points in your grid, generate them all using meshgrid, then vectorize the computation by calculating your values all at once rather than individually. Once you do this, you have the right structure to be able to put this into mesh.
Therefore, try doing this instead:
%// Define meshgrid of points
[alpha,beta] = meshgrid(0.1:0.1:5, 0.1:0.1:5);
%// From your code
sigma = 1;
%// Calculate quantities - Notice that this is all vectorized
med=sqrt(2*(sigma^2)*beta.*gammaincinv(0.5,alpha));
q1=sqrt(2*(sigma^2)*beta.*gammaincinv((6/8),alpha));
q3=sqrt(2*(sigma^2)*beta.*gammaincinv((2/8),alpha));
q4=sqrt(2*(sigma^2)*beta.*gammaincinv((7/8),alpha));
q5=sqrt(2*(sigma^2)*beta.*gammaincinv((5/8),alpha));
q6=sqrt(2*(sigma^2)*beta.*gammaincinv((3/8),alpha));
q7=sqrt(2*(sigma^2)*beta.*gammaincinv((1/8),alpha));
galtonskewness=(q1-2*med+q3)./(q1-q3);
moorskurtosis=(q4-q5+q6-q7)./(q1-q3);
%// Show our meshes
figure;
mesh(alpha, beta, galtonskewness);
figure;
mesh(alpha, beta, moorskurtosis);
Also take note that I renamed your median variable to med. MATLAB has a function called median and so you don't want to unintentionally shadow over this function with a variable of the same name.
This is what I get:
Take note that I'm not getting the plots that you have placed in your post. It may be because I'm choosing the wrong variables to define the mesh, or perhaps your equations may be incorrect. Double check what you know in theory to what you have here in code and try again.
This should hopefully give you enough to start with though!

Matlab: Placing Zeros In A Three Dimensional Matrix

I am using a for loop to calculate the electric potential on a subset of the xy-plane (a square grid). Here is the code:
L=2;
for i=1:L
for j=1:L
for k=1:L
V(i,j,k)= -10;
end
end
end
where L is the length of the subset of the xy-plane. The difficulty I am having, however, is that I want the z component of the electric potential to be zero, I just want to the region in the xy-plane to be nonzero. The reason why I am using three dimensions is because I am going to eventually introduce an object, which is at a different electric potential relative to the plane, that is above the plane.
What I tried was taking a simple two dimensional matrix:
a =
1 1 1
1 1 1
and tried replacing the ones in the second column with zeros, which I did by typing a(:,2)=0, and matlab gave me
a =
1 0 1
1 0 1
I then tried to generalize this to a 3 dimensional matrix, but ran into some difficulty. Could someone help me?
I assume you want to set the 2nd component of a 3 dimensional matrix to zero.
You can do this in the same way as you do for 2 dimensional case.
A = ones(3,3,3) % Never use For Loops the way you did for operating on matrices.
A(:,2,:) = 0
%allocate the matrix:
V=nan(L,L,L)
%fill z=0 with intended potential. Assign a scalar to have identical
%values or a matrix to set individually
V(:,:,1)=-10
%set all other numbers to zero:
V(:,:,2:end)=0
You could merge the first and third step by allocating with zeros(L,L,L), but I think this way it's more obvious.