Plotting cdf and regular graph in same axis in matlab - matlab

I have a vector with 1000 random numbers called v. I also have a vector, called x that represents the domain of which the numbers in v are generated, and another vector y that has the numbers of the cdf of the values in v. I know that I can do plot(x,y); and get a smooth function of the (non-empirical) cdf, and I also know that I can do cdfplot(v) to get a function of the empirical cdf.
My question is: How can I get these plots on the same set of axis?
Thank you for your help.

You could either generate data for an empirical cdf plot using ecdf or plot it directly with cdfplot like you mentioned. I would recommend using cdfplot since it sets up a few more things, such as a grid:
hFig = figure;
cdfplot(v);
hold all;
plot(x, y);
And as a bonus! Consider showing the X axis in logarithmic units, whichever reveals the data the best for you:
hAxes = get(hFig, 'CurrentAxes');
set(hAxes, 'XScale', 'log')

Related

how to find fourier coefficients in matlab using approximate amount?

i have this formula to find fourier series in matlab
f(n)= (f(t),exp(jnt))
and the inner product is: =(1\2*pi)integral((between pi and
-pi)(f1*f2'*dt))
now i want to find fourier coefficients in matlab for this vector(f(t)=t)
where t is a vector that it's lenght is 1000.
i need to find the 2k+1 fourier coefficients by approximate amount when k=2 , which means n=(-2,-1,0,1,2) and then Compare it to the Analytical Calculation.
this is what i did so far:
clc
t = linspace(-pi,pi,1000);
f=t;
plot(t,f); hold all;
dt=2*pi/1000;
cnPlusVal=0;
cnMinusVal=0;
FourierS1=0;
FourierS2=0;
k=2;
for l = 1:k
cnPlusVal=cnPlusVal+f.*exp(-i*l*t)*(dt/2*pi) ;
cnMinusVal=cnMinusVal+f.*exp(i*l*t)*(dt/2*pi);
FourierS1=FourierS1+cnPlusVal.*(exp(i*l*t));
FourierS2=FourierS2+cnMinusVal.*(exp(i*-l*t));
end
now in order to Compare it to the Analytical Calculation i need to plot the forier series .. any help of how to do this in the same graph for f ?
You have two problems to deal with here:
your first plot is on a completely different scale when compared to the output series;
you cannot infer a good axis scope using the limits of the series, because they contain complex numbers.
Here is the workaround I propose you:
figure();
plot(t,FourierS1);
x_lim = get(gca(),'XLim');
y_lim = get(gca(),'YLim');
hold on;
plot(t,f);
set(gca(),'XLim',x_lim,'YLim',y_lim);
hold off;
Basically:
you plot the Fourier serie;
you retain the current x-axis and y-axis limits of the plot;
you plot f over the current plot using the hold function properly;
you revert the plot limits to the previous scope.
Here is the output:

MATLAB Wigner plot for Matching Pursuit atoms

Using MATLAB I apply Matching Pursuit to approximate a signal. My problem is that I struggle to visualize the time-frequency representation of the selected atoms. I'm trying to produce a Wigner plot similar to the following image (source).
I have looked into the Wavelet Toolbox, Signal Processing Toolbox as well as the open source Time-Frequency Toolbox, but I'm possibly just using the wrong parameters, since my experience with signal processing is quite limited.
Example
Using this data my goal is to reproduce the plot from above.
% fit the signal using MP
itermax = 50;
signal = load('signal.txt');
dict = wmpdictionary(length(signal));
[signal_fit, r, coeff, iopt, qual, X] = wmpalg('OMP', signal, dict, ...
'itermax', itermax);
% wigner plot of the simulated signal
tfrwv(signal_fit) % wigner-ville function from time-frequency toolbox
% wigner plot of each atom
atoms = full(dict(:, iopt)) % selected atoms
for i = 1:itermax
tfrwv(atoms(:, i))
end
Unfortunately, none of the resulting plots comes close to the target visualization. Note, that in the example I use tfrwv with standard parameters which I tweak with the GUI that it opens.
I'd greatly appreciate your help.
Update
I think I have now understood that one needs to use Gabor atoms to get blobs with shapes resembling stretched gaussians. Unfortunately, there are no Gabor functions in the predefined dicts of the Signal Processing Toolbox. However, this question helped me in implementing the needed dictionaries, such that I get atoms which look quite similar to the example:
Since my plots come close but are not perfect, there are still two questions open:
Can all of the blobs that we see in the first example be modeled by Gabor atoms alone, or do I need another dictionary of functions?
How can I combine the indidividual imagesc plots into a single visualization?
To answer your second question 'How can I combine the indidividual imagesc plots into a single visualization?'
If you have multiple 2d matrices that you want to superimpose and display using imagesc, I would suggest taking the element-wise maximum.
For example, I generate two 31x31 grids with gaussians with different mean and variance.
function F = generate2dGauss(mu, Sigma)
x1 = -3:.2:3; x2 = -3:.2:3;
[X1,X2] = meshgrid(x1,x2);
F = mvnpdf([X1(:) X2(:)],mu,Sigma);
F = reshape(F,length(x2),length(x1));
end
F1 = generate2dGauss([1 1], [.25 .3; .3 1]);
F2 = generate2dGauss([-1 -1], [.1 .1; .1 1]);
I can plot them with subplots as in your example,
figure;
subplot(1,2,1);
title('Atom 1');
imagesc(F1);
subplot(1,2,2);
title('Atom 2');
imagesc(F2);
Or I can plot the per element maximum of the two grids.
figure;
title('Both Atoms');
imagesc(max(F1, F2));
You can also experiment with element-wise means, sums, etc, but based on the example you give, I think maximum will give you the cleanest looking result.
Possible pros and cons of different functions:
Maximum will work best if your atoms always have zero-valued backgrounds and no negative values. If the background is zero-valued, but the atoms also contain negative values, the negative values may be covered up by the background of other atoms. If your atom's overlap, the higher value will of course dominate.
Mean will make your peaks less high, but may be more intuitive where you have overlap between atoms.
Sum will make overlapping areas larger valued.
If you have non-zero backgrounds, you could also try using logical indexing. You would have to make some decisions about what to do in overlapping areas, but it would make it easy to filter out backgrounds.
Q. How can I combine the indidividual imagesc plots into a single visualization?
A. Use subplot to draw multiple plots, find below sample with 2 by 2 plots in a figure. Change your equations in code
x = linspace(-5,5);
y1 = sin(x);
subplot(2,2,1)
plot(x,y1)
title('First subplot')
y2 = sin(2*x);
subplot(2,2,2)
plot(x,y2)
title('Second subplot')
y3 = sin(4*x);
subplot(2,2,3)
plot(x,y3)
title('Third subplot')
y4 = sin(6*x);
subplot(2,2,4)
plot(x,y4)
title('Fourth subplot')

MATLAB: Plotting different numerical approximation in one plot

I have the following matlab code for approximating a differential equation via the Euler-method:
% Eulermethod
a=0;
b=0.6;
Steps=6;
dt=(b-a)/Steps;
x=zeros(Steps+1,1);
x(1,1)=1;
y=zeros(Steps+1,1);
for i=1:Steps
x(i+1,1)=x(i,1)+dt*(x(i,1)*x(i,1)+1);
end
plot(x)
I want to be able to plot the solution plot for several different values of Steps in one plot and have the x-axis go from 0 to 0.6 instead of from for example 1 to 100 000 etc. Can this be done?
If you use the hold on command this will allow you achieve multiple plots on the same figure. Similarly, if you separate your data into x and y vectors, you can plot them against eachother by passing 2 vectors to plot instead of just one. For example
figure
hold on
for i=1:m
x = [];
y = [];
%% code to populate your vectors
plot(x,y)
end
You should now see all your plots simultanesously on the same figure. If you want x to be composed of n equally spaced elements between 0 and 0.6, you could use the linspace command:
x = linspace(0.0,0.6,n);
In order to distinguish your plots, you can pass an extra paramter to the function .For example
plot(x,y,'r+')
will plot the data as a series of red + symbols.
Plot can take more arguments: plot(x_axis,values, modifiers);
If x-axis is a vector of M elements, values can be a matrix of MxN elements, each of which are drawn with a separate color.

How can I find equation of a plot connecting data points in Matlab?

I have various plots (with hold on) as show in the following figure:
I would like to know how to find equations of these six curves in Matlab. Thanks.
I found interactive fitting tool in Matlab simple and helpful, though somewhat limited in scope:
The graph above seems to be linear interpolation. Given vectors X and Y of data, where X contains the arguments and Y the function points, you could do
f = interp1(X, Y, x)
to get the linearly interpolated value f(x). For example if the data is
X = [0 1 2 3 4 5];
Y = [0 1 4 9 16 25];
then
y = interp1(X, Y, 1.5)
should give you a very rough approximation to 1.5^2. interp1 will match the graph exactly, but you might be interested in fancier curve-fitting operations, like spline approximations etc.
Does rxns stand for reactions? In that case, your curves are most likely exponential. An exponential function has the form: y = a*exp(b * x) . In your case, y is the width of mixing zone, and x is the time in years. Now, all you need to do is run exponential regression in Matlab to find the optimal values of parameters a and b, and you'll have your equations.
The advice, though there might be better answer, from me is: try to see the rate of increase in the curve. For example, cubic is more representative than quadratic if the rate of increase seems fast and find the polynomial and compute the deviation error. For irregular curves, you might try spline fitting. I guess there is also a toolbox in matlab for spline fitting.
There is a way to extract information with the current figure handle (gcf) from you graph.
For example, you can get the series that were plotted in a graph:
% Some figure is created and data are plotted on it
figure;
hold on;
A = [ 1 2 3 4 5 7] % Dummy data
B = A.*A % Some other dummy data
plot(A,B);
plot(A.*3,B-1);
% Those three lines of code will get you series that were plotted on your graph
lh=findall(gcf,'type','line'); % Extract the plotted line from the figure handle
xp=get(lh,'xdata'); % Extract the Xs
yp=get(lh,'ydata'); % Extract the Ys
There must be other informations that you can get from the "findall(gcf,...)" methods.

How to create 3D joint density plot MATLAB?

I 'm having a problem with creating a joint density function from data. What I have is queue sizes from a stock as two vectors saved as:
X = [askQueueSize bidQueueSize];
I then use the hist3-function to create a 3D histogram. This is what I get:
http://dl.dropbox.com/u/709705/hist-plot.png
What I want is to have the Z-axis normalized so that it goes from [0 1].
How do I do that? Or do someone have a great joint density matlab function on stock?
This is similar (How to draw probability density function in MatLab?) but in 2D.
What I want is 3D with x:ask queue, y:bid queue, z:probability.
Would greatly appreciate if someone could help me with this, because I've hit a wall over here.
I couldn't see a simple way of doing this. You can get the histogram counts back from hist3 using
[N C] = hist3(X);
and the idea would be to normalise them with:
N = N / sum(N(:));
but I can't find a nice way to plot them back to a histogram afterwards (You can use bar3(N), but I think the axes labels will need to be set manually).
The solution I ended up with involves modifying the code of hist3. If you have access to this (edit hist3) then this may work for you, but I'm not really sure what the legal situation is (you need a licence for the statistics toolbox, if you copy hist3 and modify it yourself, this is probably not legal).
Anyway, I found the place where the data is being prepared for a surf plot. There are 3 matrices corresponding to x, y, and z. Just before the contents of the z matrix were calculated (line 256), I inserted:
n = n / sum(n(:));
which normalises the count matrix.
Finally once the histogram is plotted, you can set the axis limits with:
xlim([0, 1]);
if necessary.
With help from a guy at mathworks forum, this is the great solution I ended up with:
(data_x and data_y are values, which you want to calculate at hist3)
x = min_x:step:max_x; % axis x, which you want to see
y = min_y:step:max_y; % axis y, which you want to see
[X,Y] = meshgrid(x,y); *%important for "surf" - makes defined grid*
pdf = hist3([data_x , data_y],{x y}); %standard hist3 (calculated for yours axis)
pdf_normalize = (pdf'./length(data_x)); %normalization means devide it by length of
%data_x (or data_y)
figure()
surf(X,Y,pdf_normalize) % plot distribution
This gave me the joint density plot in 3D. Which can be checked by calculating the integral over the surface with:
integralOverDensityPlot = sum(trapz(pdf_normalize));
When the variable step goes to zero the variable integralOverDensityPlot goes to 1.0
Hope this help someone!
There is a fast way how to do this with hist3 function:
[bins centers] = hist3(X); % X should be matrix with two columns
c_1 = centers{1};
c_2 = centers{2};
pdf = bins / (sum(sum(bins))*(c_1(2)-c_1(1)) * (c_2(2)-c_2(1)));
If you "integrate" this you will get 1.
sum(sum(pdf * (c_1(2)-c_1(1)) * (c_2(2)-c_2(1))))