smoothing 2D plot in MATLAB - matlab

I have some simple plot like this in MATLAB:
x = [0:5:25];
y = [1 4 7 9 8 3];
plot(x,y)
My question is how can I smooth it? Haven't found any way of doing what I want in documentation.

You can use a cubic smoothing spline
p = 1e-2; % initialize smoothing constant
fn = csaps(x, y, p); % get ppform of the cubic smoothing spline
y1 = ppval(fn, x); % evaluate piecewise polynomial
For comparison:
plot(x,y);
hold on;
plot(x, y1, '-r');

Maybe you could make use of spline as follows
x1 = 0:.1:25;
y1 = spline(x,y,x1);
plot(x,y,x1,y1);

Related

Is there an accurate curve fitting method that returns coefficients which can be used to generate the original curve back via a function? (Matlab)

Take a set of data and plot a curve.
Take the curve and apply curve fitting to generate coefficients.
Use coefficients to generate the curve back via a function.
Currently tried polynomial with nth orders, but is very inaccurate. Also tried spline which is accurate but does not allow the curve to be regenerated only using a function.
I think you are probably looking for a spline fit & method. MATLAB spline objects do allow a curve to be regenerated using only a function (ppval).
e.g.
% original curve 1
x = linspace(0, 4);
y = cos(2 * pi * x);
subplot 221
plot(x, y)
title('Original Curve 2')
% fitted curve 1
p = pchip(x, y);
s = spline(x, y);
subplot 223
plot(x, ppval(p, x), x, ppval(s, x))
legend('pchip','spline')
title('Fitted Curve 1')
% original curve 2
nSample = 1001;
x = linspace(0, 1e-2, nSample);
nPulse = 9;
c = [linspace(0.001, 0.009, nPulse); (7/8).^(1:nPulse)]';
y = pulstran(x, c, #gauspuls, 10000, 0.5);
subplot 222
plot(x, y)
title('Original Curve 2')
% fitted curve 2
p = pchip(x, y);
s = spline(x, y);
subplot 224
plot(x, ppval(p, x), x, ppval(s, x))
legend('pchip','spline')
title('Fitted Curve 2')

How to create noise for a 2D Gaussian?

I'm trying to practice curve fitting on a 2D Gaussian, but in order to do that I need to add random noise to my predefined Gaussian. My first instinct was to cycle through two for loops and create two matrices X and Y with random numbers, but when I tried that (I don't have the code anymore) Matlab wouldn't let me plot the Gaussian because I didn't generate my X and Y values using the meshgrid function. Since I seem to need to use meshgrid, can anyone help me figure out how to generate a random meshgrid so I can add some noise to my Gaussian?
amp = 1;
x0 = 0;
y0 = 0;
sigmaX = 1;
sigmaY = 1;
%X = 1:1:100;
%Y = 1:1:100;
[X,Y] = meshgrid(-3:.1:3);
%Z = X .* exp(-X.^2 - Y.^2);
Z = amp*exp(-((X-x0).^2/(2*sigmaX^2)+(Y-y0).^2/(2*sigmaY^2)));
surf(X, Y, Z);
%Add noise now
EDIT: So I found out that rand can return a random matrix which will work with the surf function (for some reason it wasn't working for me earlier though). The result looks something like this: noisy 2D gaussian
amp = 1;
x0 = 0;
y0 = 0;
sigmaX = 1;
sigmaY = 1;
[X,Y] = meshgrid(-3:.1:3);
%Z = X .* exp(-X.^2 - Y.^2);
Z = amp*exp(-((X-x0).^2/(2*sigmaX^2)+(Y-y0).^2/(2*sigmaY^2)));
surf(X, Y, Z);
%Make some noise
[xRows, xColumns] = size(X);
[yRows, yColumns] = size(Y);
figure(2)
X = -.1 + (.1+.1)*rand(61,61);
Y = -.1 + (.1+.1)*rand(61,61);
Z = amp*exp(-((X-x0).^2/(2*sigmaX^2)+(Y-y0).^2/(2*sigmaY^2)));
surf(X, Y, Z)
But I feel like the Gaussian has largely lost it's typical bell shape and looks more like a slope field than anything. I'm going to try and refine it but I would love any input.
That's what i would do.
amp=1;
x0=0;
y0=0;
sigmaX=1;
sigmaY=1;
noiseAmp=.1;
x=[-2:.1:2];
y=[-2:.1:2];
%Create two Noise Vectors
noisez1=noiseAmp.*rand(1,length(x));
noisez2=noiseAmp.*rand(1,length(x));
% Make an meshgrid out of the two Vectors
[noiseZ1,noiseZ2]=meshgrid(noisez1,noisez2);
% Add the Meshgrids togehter
Noise=noiseZ1+noiseZ2;
[X,Y]=meshgrid(x,y);
% Add the Noise to the result of Z
Z=amp*exp(-((X-x0).^2/(2*sigmaX^2)+(Y-y0).^2/(2*sigmaY^2)))+Noise;
surf(X,Y,Z);
if you just want a 2D plot you can try this
amp=1;
noiseAmp=0.01;
x0=0;
y0=0;
sigmaX=1;
sigmaY=1;
x=[-5:.01:5];
noiseY=noiseAmp*rand(1,length(x));
y=noiseY+amp*exp(-((x-x0).^2/(2*sigmaX^2)));
plot(x,y);
where noiseAmp is the Amplitude of the noise.
But if you still want to create a 3D plot with the surf() function, you have to add a random meshgrid to the Z result.

Plotting Ellipse for complex values in matlab

I am trying to plot the elliptical trajectory of a particle, but my matlab code runs and gives me warning that I m trying to plot imaginary values. How can I remove this error?
My Matlab code is as follows:
% plot of trajectory of the particle in flexural gravity wave
U =5;
t=1;
y1=0;
h=50;
k=2*pi/100;
w=pi;
X= (-80*pi:pi:80*pi);
Y= (-80*pi:pi:80*pi);
H=1;
A= (H/2)*cosh(k*(h+y1))/sinh(k*h);
B= (H/2)*sinh(k*(h+y1))/sinh(k*h);
Y = B.* ((1-((X-U*t)./A).^2).^(1/2));
plot(X,Y);
xlabel('X');
ylabel('Y');
The warning matlab shows is:
Warning: Imaginary parts of complex X and/or Y arguments ignored
Please help me out with this.
If you want to plot imaginary number only,
Please change the code, plot(X,Y); as plot(X,imag(Y)).
In case of real value, plot(X,real(Y)).
If you are interested in magnitude of complex number, plot(X,abs(Y)).
I got the answer to my question.
I can plot it by using general coordinates of the ellipse, ie, using x=acos(t) and y=asin(t). and that really worked.
% plot of trajectory of the particle in flexural gravity wave
U = 5;
t = 1;
y1 = 0;
h = 50;
k = 2*pi/100;
w = pi;
x0 = U*t;
y0 = 0;
H = 1;
A = (H/2)*cosh(k*(h+y1))/sinh(k*h);
B = (H/2)*sinh(k*(h+y1))/sinh(k*h);
z = -2*pi:0.01:2*pi;
X = x0 + A*cos(z);
Y = y0 + B*sin(z);
plot(X,Y);
xlabel('X');
ylabel('Y');

plotting a bullet-nose curves

I would like to plot this function of Two Variables you can find it here
$$z^2=t(t-i) \Longleftrightarrow x^2+y^2=4x^2y^2 \Longleftrightarrow y=\dfrac{\pm x}{\sqrt{4x^2-1}} \mbox{ with } |x|>\frac{1}{2}$$
would someone show me step by step how to plot this in matlab
is there any script or toolbox in http://www.mathworks.com/matlabcentral/fileexchange
which make plot of that kind of curves quickly
this is by geogebra
This is by wolframe
You can use symbolic variables with ezplot.
syms x y % makes symbolic variables
h1 = ezplot('-4*x^2*y^2+x^2+y^2'); % plots the equation
axis equal
set(h1, 'Color', 'k');
Or you can define a function,
f = #(x,y) -4.*x.^2.*y.^2+x.^2+y.^2;
h1 = ezplot(f);
set(h1, 'Color', 'k');
It won't be easy to have the axis in the middle, I hope it's not necessary to have that.
Edit
You can download oaxes here
syms x y
h1 = ezplot('-4*x^2*y^2+x^2+y^2');
axis equal
set(h1, 'Color', 'm');
oaxes('TickLength',[3 3],'Arrow','off','AxisLabelLocation','side',...
'LineWidth',1)
Edit
For 3D plot try this,
% First line provides a grid of X and Y varying over -5 to 5 with .5 as step-size
[X,Y] = meshgrid(-5:.5:5);
% instead of "=0", Z takes the values of the equation
Z = -4 .* X.^2 .* Y.^2 + X.^2 + Y.^2;
surf(X,Y,Z) % makes a 3D plot of X,Y,Z
You can also try contourf(X,Y,Z) for 2D plot.

Two Gaussian distribution plot on the same axis

I am trying to plot two Gaussian distribution both with mean zero, one with variance 1 and the other with variance 2 on the same axis. Here is my code.
X= 0 + 1.*randn(2,500);
plot(X(1,:),X(2,:),'x');
hold on
%plot(m(1),m(2),'r*')
Y= 0 + 2.*randn(2,500);
plot(Y(1,:),Y(2,:),'gx')
Please check and see if i have done it correctly. I also want to have them in 2-D plot and superimpose.
Thanks.
You are plotting the data you have randomly generated (with a normal distribution). If that's what you want, yes, it works ok.
If you want to plot the density functions of the variables, you can do it the following way:
mu = 0;
sigma1 = 1;
sigma2=2;
x = -4*sigma2:1e-3:4*sigma2;
y1 = pdf('normal', x, mu, sigma1);
y2 = pdf('normal', x, mu, sigma2);
plot(x, y1)
hold on
plot(x, y2, 'r')
legend('mu=0, sigma=1', 'mu=0, sigma=2')
title('Density functions')