Animated Discrete Stem Plot - matlab

So I want to create an animated plot of a discrete-time complex exponential function. The simplest non-animated plot would be given by this:
n=-5:40;
x=(exp((3*4j)*n)).*(n>=0);
y=real(x);
subplot(2,1,1);
stem (n,y)
z=imag(x);
subplot(2,1,2);
stem (n,z)
How do I animate it to show the function for the different numbers of samples considered in a given interval (assuming I have a time interval specified by start second and end second and a vector containing the number of sample values in the given interval)?
I tried along these lines:
figure,hold on
xlim([min(x(:)) max(x(:))])
ylim([min(y(:)) max(y(:))])
%// Plot point by point
for k = 1:numel(x)
stem (k,y) %// Choose your own marker here
pause(0.001);
end
That doesn't compile. How to achieve this?

Short answer:
Make the following two changes:
① Replace xlim([min(x(:)) max(x(:))]) with this xlim([1 numel(x)]).
② Replace stem (k,y) with this: stem (k,y(k)).
Detailed Answer:
① xlim([min(x(:)) max(x(:))]) is giving you the following error:
Error using matlab.graphics.axis.Axes/set
While setting the 'XLim' property of 'Axes':
This is not a valid LimitsWithInfs value. Complex inputs are not supported
The error message tells you exactly what the problem is. Your vector x contains complex numbers. Time axis having complex numbers also doesn't imply anything.
It seems that you would want to replace this line xlim([min(x(:)) max(x(:))]) with this: xlim([1 numel(x)]).
② Inside the loop, stem (k,y) is giving you this error:
Error using stem (line 46)
X must be same length as Y.
The error message tells you exactly what the problem is. Here k is just a scalar (1x1) but y is a 1x46 vector. Since you want to plot y point by point, replace stem (k,y) with this: stem (k,y(k)).
Output after making the mentioned fixes:

Related

Interpolate a scalar field over a 3D mesh refining the grid

I have function f=f(x,y,z) computed numerically over a grid of points of size MxNxP.
I need to interpolate that values over a finer grid of (obviously) different dimensions. Like I do with interp1 when I have only some values of a function over an interval and I want to interpolate it to find the values at more points.
I tried executing this code:
XX=linspace(0,45,50);
YY=linspace(0,0.5,50);
ZZ=linspace(0,0.5,50);
U_1 = interp3(X,Y,Z,f,XX,YY,ZZ,'linear')
where X Y Z are the vectors of points where I have the values of f. XX,YY,ZZ are the points where I want the solution.
I tried with griddata and also with interp3 but I got the following error message:
Error using griddedInterpolant
The grid vectors do not define a grid of points that match the given values.
Error in interp3 (line 133)
F = griddedInterpolant({X, Y, Z}, V, method,extrap);
Could you help me, please?
You seem to have an irregular gridded data set. In this case you need to use the griddata() function to interpolate.
Take care that your defining point arrays X,Y,Z have equal dimensions. Also the interpolant point arrays XX,YY,ZZ have to have equal dimensions.
That means the following expression must be true (or 1):
all(size(X)==size(Y)) && all(size(X)==size(Z)))
For the creation of your interpolants you may use meshgrid. It is wise to adapt the range of your interpolation grid to your real data range:
[XX,YY,ZZ]=meshgrid(linspace(min(X(:)),max(X(:)),50), ...
linspace(min(Y(:)),max(Y(:)),50), ...
linspace(min(Z(:)),max(Z(:)),50));
This will probably give the result you expect.

plotting 2 variable of different size in matlab

Am trying to plot 2 variable of different size length in matlab GUI using push button,
but because the variables are of different length it will not work,is there a way i can make it to plot.
d= pdist([x,y,z],'euclidean') ; % value of my distance
dd= 1:10:d; % interval and end 'd' value
FSL=-120; %value of free space loss get from the GUI
DFSL= 1:10:FSL %interval and end at FSL value
plot(dd,DFSL)
The plot code didnt work coming back with an error "
Error using plot
Vectors must be the same lengths"
You can plot vectors of two different lengths, but not against each other. You have used the syntax
plot(x,y)
which means for every element in vector x, there should be a corresponding element in vector y. In your case, you do not have this, hence the error.
You can plot like this though:
plot(x)
figure;
plot(y)
If you are looking to plot them in a single plot, subplot will be useful.

Plotting 3 vectors in Matlab GUI axes handle

I am trying to plot 3 vectors onto matlab GUI in a serial object's callback.
I want to plot this on axes handle but the problem is it only plot last vector;
plot(handles.axes1,sensor1,'r');
plot(handles.axes1,sensor2,'b');
plot(handles.axes1,sensor3,'g');
I searched on internet and find that this issue can be solved with hold on and hold of feature so I tried this
plot(handles.axes1,sensor1,'r');
hold on ;
plot(handles.axes1,sensor2,'b');
plot(handles.axes1,sensor3,'g');
hold off;
but in this case a new figure is opened(dont know why) and again only the last plot is drawn.
I am stucked. If any one have idea of what would be the issue?
Thanks
I'm not sure why your first try using "hold" didn't work. Seems like it should have.
But in any case, you can get the desired behavior in a single command:
plot(handles.axes1,length(sensor1),sensor1,'r',...
length(sensor2),sensor2,'b',...
length(sensor3),sensor3,'g');
This specifies both an X = length(sensor_) and a Y = sensor_ to the plot command. When you only give plot a Y input, it assumes an X of length(Y). But you can't combine multiple traces in a single plot command by giving only the Y input for each, because it will try to treat the inputs as X,Y pairs.
As the vectors are the same length we can simply combine them as the columns of a matrix and then plot the matrix
plot(handles.axes1,[sensor1',sensor2',sensor3'])
However these will have the default colour order. Without specifying x values setting colors within the plot command is tricky. However (luckily) the default order starts:
blue,green,red...
so swapping the column order will plot the lines with the colours requested
plot(handles.axes1,[sensor2',sensor3',sensor1'])
(this assumes the vectors are rows, if they are columns don't transpose them)

Matlab plot of a function with 2 variables

I have a problem to plot a function with 2 variables:
if i do:
x= linspace(0,5);
y=linspace(0,5);
[x,y]=meshgrid(x,y);
z=log(x.*sqrt(y-x));
mesh(x,y,z);
I get this error:
Error using mesh (line 76) X, Y, Z, and C cannot be complex.
I think because I have some complex results in the computation.
How could I solve?
What kind of output do you expect? It's possible to plot the absolute value using mesh(x,y,abs(z));, but I'm not sure if this is what you want. quiver is another possibility to plot your data.
The reason you are getting complex results is the sqrt(y-x) part in your code. y is less than x at almost half of the points of your grid which leads to computing the square root of a negative number.
So, as Daniel suggested, you can use abs(z). Alternatively you could check if it is OK for the particular application to compute sqrt(abs(y-x)) to make sure you have a positive number under the square root

How to plot this equation in MATLAB? Keep getting matrix dimension errors

The code I have is:
T=[0:0.1:24];
omega=((12-T)/24)*360;
alpha = [0:1:90];
latitude=35;
delta=[-23.45:5:23.45];
sind(alpha)=sind(delta).*sind(latitude)+cosd(delta).*cosd(latitude).*cosd(omega)
cosd(phi)=(sind(alpha).*sind(latitude)-cosd(delta))./(cosd(alpha).*cosd(latitude))
alpha represents my y-axis and is an angle between 0 and 90 degrees. phi represents my x-axis and is an angle between say -120 to +120. The overall result should look something like a half sine-wave.
Whenever I try to input that last line I get the error stating inner matrix dimensions must agree. So I tried to use reshape on my matrices for those variables I defined so that they work. But then I get '??? ??? Subscript indices must either be real positive integers or logicals.'
It seems very tedious to have to reshape my matrix every time I define a new set of variables in order to use them with an equation. Those variables are used for defining my axis range, is there a better way I can lay them out or an automatic command that will make sure they work every time?
I want to plot alpha and phi as a graph using something like
plot(alpha,phi)
but can't get past those errors? can't I just use a command that says something like define x-axis [0:90], define y-axis [-120:120] or something? I have spent far too much time on this problem and can't find a solution. I just want to plot the graph. Somebody please help! thanks.
Thanks
Here is a start for you:
% Latitude
L=35;
% Hour Angle
h = [-12:5/60:12];
w = 15*h;
% Initialize and clear plot window
figure(1); clf;
% Plot one day per month for half of the year
for N = 1:30:365/2
% Declination
d = 23.45*sind(360*(284+N)/365);
% Sun Height
alpha = asind(sind(L)*sind(d) + cosd(L)*cosd(d)*cosd(w));
% Solar Azimuth
x = ( sind(alpha)*sind(L)-sind(d) )./( cosd(alpha)*cosd(L) );
y = cosd(d)*sind(w)./cosd(alpha);
phi = real(atan2d(y,x));
% Plot
plot(phi,alpha); hold on;
end
hold off;
grid on;
axis([-180, 180, 0, 90]);
xlabel('Solar Azimuth')
ylabel('Solar Elevation')
The function asind is inherently limited to return values in the range of -90 to 90. That means that you will not get a plot that spans over 240 degrees like the one you linked to. In order for the plot to not have the inflection at +/- 90 degrees, you will need to find a way to infer the quadrant. Update: I added the cosine term to get an angle using atan2d.
Hopefully this will be enough to give you an idea of how to use Matlab to get the kind of result that you are after.
Element-wise multiplication (.*) and division ./, not the matrix versions:
sind(alpha)=sind(delta).*sind(latitude)+cosd(delta).*cosd(latitude).*cosd(omega)
cosd(phi)=(sind(alpha).*sind(latitude)-cosd(delta))./(cosd(alpha).*cosd(latitude))
But a bigger problem is that you can't index with decimal or non-positive values. Go back to the code before you got the subscript indices error. The indices "must either be real positive integers or logicals".
I think you're a bit confused about MATLAB sintax (as nispio mentioned). Maybe you want to do something like this?
T=[0:0.1:24];
omega=((12-T)/24)*360;
alpha = [0:1:90];
latitude=35;
delta=[-23.45:5:23.45];
[o1,d1]=meshgrid(omega,delta);
[a2,d2]=meshgrid(alpha,delta);
var1=sind(d1(:)).*sind(latitude)+cosd(d1(:)).*cosd(latitude).*cosd(o1(:));
var2=(sind(a2(:)).*sind(latitude)-cosd(d2(:)))./(cosd(a2(:)).*cosd(latitude));
plot(var1);hold on;plot(var2);
If not, you should post the algorithm or pseudocode