Drawing a line in matlab plot - matlab

I am beginner in matlab programming, so i wrote this little programm to see it in action, and now I have a little problem because I am not sure why it is not working.
x = zeros(50);
squared = zeros(50);
cubed = zeros(50);
for num = 1:50
x(num) = num;
squared(num) = num^2;
cubed(num) = num^3;
end
% calculate the mean
mean_cubed = mean(cubed);
% clear screen and hold the plot
clf;
hold on
plot(x, squared);
plot(x, cubed);
plot([0, 50], [mean_cubed, mean_cubed]);
hold off
The main program is when i start the program i get a error:
Error using plot
Vectors must be the same lengths.
Error in basic_mathlab_plotting_2 (line 20)
plot([0, limit], [mean_cubed, mean_cubed]);
I think the size of vector are the same, so i dont know what is wrong.
Thanks!!!

In the first lines, you probably meant
x = zeros(1,50);
squared = zeros(1,50);
cubed = zeros(1,50);
Note that zeros(50) is equivalent to zeros(50,50) and so it returns a 50x50 matrix.
In addition, those lines and the for loop could be replaced by
x = 1:50;
squared = x.^2;
cubed = x.^3;
This applies the important concept of vectorization, by using the element-wise power operation.

Related

Error using stem X must be same length as Y

im trying to find the even and odd part of the x array but it returns me error using stem, X must be same length as Y this is my code in matlab
close all;
clear all;
clc;
n1 = -5:1:5;
AM = 19390;
x = [1,9,3,9,0,1,1,9,3,9,0];
fun(x,n1);
function [sima,xr] = fun(t,x)
x_reverse = fliplr(x);% time reversal
sima = 0.5*(x + x_reverse); %even component
xr = 0.5*(x - x_reverse); %odd component
subplot(3,1,1);
stem(t,x);
title('Your signal x')
subplot(3,1,2);
stem(t,sima);
title('Even part');
subplot(3,1,3);
stem(t,xr);
title('Odd part');
end
the inputs of fun are reversed.
where you write
fun(x,n1)
you should have
fun(n1,x)
this or reverse the order of each reference and value vectors for each stem inside fun.

Why can't I use 'scatter3' here?

[X,Y] = meshgrid(-8:.5:8);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
scatter3(X,Y,Z)
Error using scatter3 (line 64)
X, Y and Z must be vectors of the same length.
Matlab R2018b windows x64
As shown in the documentation, X, Y, Z must be vectors. (When you enter an article on mathworks from Googling, say, "matlab scatter3", you will first see the syntax for the function. Blue text means hyperlink. All the inputs are linked to the bottom of the page where their exact typing is defined.)
The reason is (probably) as follows.
As stated in the documentation, scatter3 puts circles (or other symbols of your choice if you modify the graphic object) on 3D coordinates of your choice. The coordinates are the ith element of X, Y, Z respectively. For example, the x-coordinate of the 10th point you wish to plot in 3D is X(10).
Thus it is not natural to input matrices into scatter3. If you know X(i), Y(i), Z(i) are indeed the coordinates you want to plot for all i, even though your X, Y, Z are not vectors for some reason, you need to reshape X, Y, Z.
In order to reshape, you can simply do scatter3(X(:), Y(:), Z(:)) which tells Matlab to read your arrays as a vectors. (You should look up in what order this is done. But it is in the intuitive way.) Or you can use reshape. Chances are: reshape is faster for large data set. But ofc (:) is more convenient.
The following should work:
[X,Y] = meshgrid(-8:.5:8);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
X = X(:);
Y = Y(:);
Z = Z(:);
scatter3(X,Y,Z)
scatter3 needs vectors, not matrices as far as I can see here
this is my result:
If you want to use meshgrid without reshaping the matrices you have to use plot3 and the 'o' symbol. So you can get a similar result with:
plot3(X,Y,Z,'o')
EDIT:
A question that arose in association with this post was, which of the following methods is more efficient in terms of computation speed: The function reshape(X,[],1), suggested by me, or the simpler colon version X(:), suggested by #Argyll.
After timing the reshape function versus the : method, I have to admit that the latter is more efficient.
I added my results and the code I used to time both functions:
sizes = linspace(100,10000,100);
time_reshape = [];
time_col = [];
for i=1:length(sizes)
X = rand(sizes(i)); % Create random squared matrix
r = #() ResFcn(X);
c = #() ColFcn(X);
time_reshape = [time_reshape timeit(r)/1000] % Take average of 1000 measurements
time_col = [time_col timeit(c)/1000] % Take average of 1000 measurements
end
figure()
hold on
grid on
plot(sizes(2:end), time_col(2:end))
plot(sizes(2:end), time_reshape(2:end))
legend("Colon","Reshape","Location","northwest")
title("Comparison: Reshape vs. Colon Method")
xlabel("Length of squared matrix")
ylabel("Average execution time [s]")
hold off
function res = ResFcn(X)
for i = 1:1000 % Repeat 1000 times
res = reshape(X,[],1);
end
end
function res = ColFcn(X)
for i = 1:1000 % Repeat 1000 times
res = X(:);
end
end

Plotting discontinuous function in MATLAB/Octave

I have not been able to find this around the web or in the docs, though that may be my due to my own incompetence. I plot functions in Octave by putting the x's in an x vector and the y's in an fx vector and then calling plot(x,fx). However, since the function has huge vertical jumps it creates unwanted vertical lines. I can do plot(x,fx,"."), but that makes the line very thick. How can I plot a discontinuous function with a thin line?
You could insert nans at your discontinuities.
A way to automate this could be to look for large difference quotients:
x = linspace(0,30,1000);
y = ceil(cos(x));
%%%%%%%%%%%%%%%%%%%%%%%
dxLimit = 10;
x = x(:).'; y = y(:).';
discontinuities = (abs(diff(y)./diff(x))>dxLimit);
x = [x; nan(1,length(x))];
y = [y; nan(1,length(y))];
x(2*find(~discontinuities)) = [];
y(2*find(~discontinuities)) = [];
x = x(:).'; y = y(:).';
%%%%%%%%%%%%%%%%%%%%%%%
plot(x,y,'-'); ylim(ylim+[-0.3,+0.3]);
In Octave, you can decrease the size of the marker like this:
x = 0:0.1:100;
fx = rand(length(x), 1)';
plot(x, fx, ".", "markersize", 1)

Matlab smooth a 3d mesh plot

Hi I have a set of data A with each element corresponding to an x and y combination. When I plot this dat using mesh I get a graph with many spikes on it. This is not unnexpected but I would like a way to smooth these out to get a smooth surface.
I've tried to use the smooth3 command but cannot figure out how to make the suitable input.
Any help would be appreciated. Thanks
This is how my data is generated.
function v = f(x,y) % Not actual function
return x*rand()+y*rand()
end
x = 0.05:0.01:0.95;
y = 0.05:0.01:0.95;
o = zeros(length(x),length(y));
A = zeros(length(x), length(y));
for k = 1:5
for i = 1:length(x)
for j = 1:length(y)
o(i,j) = f([x(i), y(j)]);
end
end
A= A+o;
end
A = A/5;
This is what produces the plot.
[X,Y] = meshgrid(x);
mesh(A)
my be you can try a convolution of your variable A with a filter(the following is an example of a Gaussian filter).
C = conv2(A,fspecial('gaussian', hsize, sigma));
check conv2 and fspecial in matlab help

Mean filter in MATLAB without loops or signal processing toolbox

I need to implement a mean filter on a data set, but I don't have access to the signal processing toolbox. Is there a way to do this without using a for loop? Here's the code I've got working:
x=0:.1:10*pi;
noise=0.5*(rand(1,length(x))-0.5);
y=sin(x)+noise; %generate noisy signal
a=10; %specify moving window size
my=zeros(1,length(y)-a);
for n=a/2+1:length(y)-a/2
my(n-a/2)=mean(y(n-a/2:n+a/2)); %calculate mean for each window
end
mx=x(a/2+1:end-a/2); %truncate x array to match
plot(x,y)
hold on
plot(mx,my,'r')
EDIT:
After implementing merv's solution, the built-in filter method lags the original signal. Is there a way around this?
Use the built-in FILTER function
%# generate noisy signal
x = sin(0:.1:10*pi);
x = x + 0.5*(rand(1,length(x))-0.5);
%# moving average smoothing
window = 15;
h = ones(window,1)/window;
y = filter(h, 1, x);
%# plot
subplot(211), plot(x), ylim([-1 1]), title('noisy')
subplot(212), plot(y), ylim([-1 1]), title('filtered')
To solve the lag problem, try something like this:
s = ceil(window/2);
yy = y(s:end);
n = length(x);
plot(1:n, x, 'b'), hold on, plot(1:n-s+1, yy,'r'), hold off
legend({'noisy' 'filtered'})