Connect different points with line in matlab - matlab

I have matrix of 2 column (x and y) and 100 rows, and each row make one point like (x1,y1).
I need to draw a line consecutively between them, like point (x1,y1) to (x2,y2) and (x2,y2) to (x3,y3) and so on till (x100,y100).
I have written this code and it's working properly. The problem is, it takes too long as I have to do this for 55000 matrix.
figure;
for j=1:length(data); % data = 55000 different matrices which should draw in the same figure
for i=1:length(data(j).x);
x= (data(j).x(i));
y= (data(j).y(i));
if i == length(data(j).x);
break;
end
x1= (data(j).x(i+1));
y1= (data(j).y(i+1));
line([x,x1],[y,y1]);
end
end
Is there any more efficient and quicker way to do that?

Try plot:
x = [];
y = [];
for j=1:length(data)
x = [x; data(j).x];
y = [y; data(j).y];
end
plot(x, y);

Related

Edit the x limits of least squares line

I created two scatter plots and then used lsline to add regression lines for each plot. I used this code:
for i=1:2
x = ..;
y = ..;
scatter(x, y, 50, 'MarkerFaceColor',myColours(i, :));
end
h_lines = lsline;
However, the darker line extends far beyond the last data point in that scatter plot (which is at around x=0.3):
lsline doesn't seem to have properties that allow its horizontal range to be set. Is there a workaround to set this separately for the two lines, in Matlab 2016a?
For a single data set
This is a workaround rather than a solution. lsline internally calls refline, which plots a line filling the axis as given by their current limits (xlim and ylim). So you can change those limits to the extent you want for the line, call lsline, and then restore the limits.
Example:
x = randn(1,100);
y = 2*x + randn(1,100); % random, correlated data
plot(x, y, '.') % scatter plot
xlim([-1.5 1.5]) % desired limit for line
lsline % plot line
xlim auto % restore axis limit
For several data sets
In this case you can apply the same procedure for each data set sequentially, but you need to keep only one data set visible when you call lsline; otherwise when you call it to create the second line it will also create a new version of the first (with the wrong range).
Example:
x = randn(1,100); y = 2*x + randn(1,100); % random, correlated data
h = plot(x, y, 'b.'); % scatter plot
axis([min(x) max(x) min(y) max(y)]) % desired limit for line
lsline % plot line
xlim auto % restore axis limit
hold on
x = 2*randn(1,100) - 5; y = 1.2*x + randn(1,100) + 6; % random, correlated data
plot(x, y, 'r.') % scatter plot
axis([min(x) max(x) min(y) max(y)]) % desired limit for line
set(h, 'HandleVisibility', 'off'); % hide previous plot
lsline % plot line
set(h, 'HandleVisibility', 'on'); % restore visibility
xlim auto % restore axis limit
Yet another solution: implement your own hsline. It's easy!
In MATLAB, doing a least squares fit of a straight line is trivial. Given column vectors x and y with N elements, b = [ones(N,1),x] \ y; are the parameters to the best fit line. [1,x1;1,x2]*b are the y locations of two points along the line with x-coordinates x1 and x2. Thus you can write (following Luis' example, and getting the exact same output):
N = 100;
x = randn(N,1); y = 2*x + randn(N,1); % random, correlated data
h = plot(x, y, 'b.'); % scatter plot
hold on
b = [ones(N,1),x] \ y;
x = [min(x);max(x)];
plot(x,[ones(2,1),x] * b, 'b-')
x = 2*randn(N,1) - 5; y = 1.2*x + randn(N,1) + 6; % random, correlated data
plot(x, y, 'r.') % scatter plot
b = [ones(N,1),x] \ y;
x = [min(x);max(x)];
plot(x,[ones(2,1),x] * b, 'r-')
You can get the points that define the line using
h_lines =lsline;
h_lines(ii).XData and h_lines(ii).YData will contain 2 points that define the lines for each ii=1,2 line. Use those to create en equation of a line, and plot the line in the range you want.

MATLAB - adding plot to another plot after loop, more sophisticatedly

i have a problem and i hope that i will find help there.
This is my example code. Its only part of my algorithm. For imagine, how the point are moving, during the equations, i need show contour of function with two variables and into the points. Becase i have more difficult function than parabolic function, so the equations are too long than i need. For this reason i move contour ploting before the loop. But i have problem. I need show countour always and points only for i-loop and my solution doesnt work. Please help me!
[R S] = meshgrid(-5:0.1:5, -5:0.1:5);
figure
contour(R, S, R.^2 + S.^2, 5);
axis([-5,5,-5,5])
axis square
hold on
for i=1:50
a = 0;
b = 1:2
B = repmat(b,5,1)
A = unifrnd(a,B)
x = A(1:5,1);
y = A(1:5,2);
scatter(x,y,'fill')
hold off
pause(0.5)
end
You should store the handle to your scatter plot and simply update the XData and YData properties of it rather than destroying the plot objects every time
[R S] = meshgrid(-5:0.1:5, -5:0.1:5);
figure
contour(R, S, R.^2 + S.^2, 5);
axis([-5,5,-5,5])
axis square
hold on
% Create a scatter plot and store the graphics handle so we can update later
hscatter = scatter(NaN, NaN, 'fill');
for i=1:50
a = 0;
b = 1:2
B = repmat(b,5,1)
A = unifrnd(a,B)
x = A(1:5,1);
y = A(1:5,2);
% Update the X and Y positions of the scatter plot
set(hscatter, 'XData', x, 'YData', y);
pause(0.5)
end

ContourPlot and inequalitie plot together

Im new to matlab and I want to plot a ContourPlot together with two inequalities but I dont know how. The function that I want to plot its ContourPlot is something like this:
Z = (X-2).^2 + (Y-1).^2;
and here are the two inequalities:
ineq1 = X.^2 - Y <= 2;
ineq2 = X + Y <= 2;
this is what I have dodne so far:
[X,Y] = meshgrid(-4:.2:4,-4:.2:4);
Z = (X-2).^2 + (Y-1).^2;
[C,h] = contour(X,Y,Z);
clabel(C,h)
ineq1 = X.^2 - Y <= 2;
ineq2 = X + Y <= 2;
range = (-4:.2:4);
hold on
plot(range,ineq1, range, ineq2)
hold off
but this does not feel right.
What I want to do is to visualize an optimization problem. First I want to plot the ContourPlot of the function and then the possible areas in that same plot, It would be great if I could show the intersection areas too.
If you want to draw the boundaries of the inequalities onto the contour plot, you can do this with line.
[X,Y] = meshgrid(-4:.2:4,-4:.2:4);
Z = (X-2).^2 + (Y-1).^2;
[C,h] = contour(X,Y,Z);
clabel(C,h)
x_vect = (-4:.05:4);
y_ineq1 = x_vect.^2 - 2;
y_ineq2 = 2 - x_vect;
line(x_vect, y_ineq1);
line(x_vect, y_ineq2);
Coloring the intersection area is a bit more tricky, and I'm not sure if it's exactly what you want to do, but you could look into using patch, something like
% Indexes of x_vect, y_ineq1 and y_ineq2 for region where both satisfied:
region_indexes = find(y_ineq1<y_ineq2);
region_indexes_rev = region_indexes(end:-1:1);
% To plot this area need to enclose it
% (forward along y_ineq1 then back along y_ineq2)
patch([x_vect(region_indexes),x_vect(region_indexes_rev)],...
[y_ineq1(region_indexes),y_ineq2(region_indexes_rev)],...
[1 0.8 1]) % <- Color as [r g b]
% May or may not need following line depending on MATLAB version to set the yaxes
ylim([-4 4])
% Get the original plot over the top
hold on
[C,h] = contour(X,Y,Z);
clabel(C,h)
hold off

plotting scatter3 and surf plots from loop in matlab

I want to plot scatter3 and surf plots from a loop. Below is my code but it isn't working...not sure where I'm going wrong but clearly something is wrong with the z matrix?
for e = 1:10;
x = rand(1,3);
y = rand(1,3);
A = x+y;
subplot(2,2,1)
p = find(A(:,1) > 1.1 & A(:,1) < 1.6);
Result = A(p,:);
scatter3(Result(:,1), Result(:,2), Result(:,3))
hold on
z(e,:) = [Result(1) Result(2) Result(3)];
end
subplot(2,2,2)
surf(z)
I will reiterate what I said in my comment to you. I got this error message when trying to run your code: Attempted to access Result(1); index out of bounds because numel(Result)=0. This is because your p condition isn't satisfied - MATLAB could not find any elements in the first column that are between 1.1 and 1.6.
As such, what I would suggest you do is check to see if Result is empty before trying to access the value itself. However, I would suggest you don't write a loop and generate all of the random values at once, then do the filtering with the Boolean conditions. Therefore, the equivalent code without using a loop would be this:
x = rand(10,3);
y = rand(10,3);
A = x+y;
p = A(:,1) > 1.1 & A(:,1) < 1.6;
z = A(p,:);
figure;
subplot(2,1,1);
scatter3(z(:,1), z(:,2), z(:,3));
subplot(2,1,2);
surf(z);
We generate 10 3D points for x and y at the beginning, then add these and store this into A. Next, we find the rows in A that are between 1.1 and 1.6 in the first column and store this as a logical array. We then use this array to index into A and store the results into z. This is the recommended approach if you want to extract certain elements into an array rather than using find.
Once we obtain z, we plot these points with scatter, then also find a surface plot with surf for the same matrix. BTW, I've fixed your subplot as you are only creating two plots, yet you are allocating space for 4 plots.
If you're absolutely bent on using your code, you would simply do this:
z = []; %// Change
for e = 1:10
x = rand(1,3);
y = rand(1,3);
A = x+y;
subplot(2,1,1)
p = find(A(:,1) > 1.1 & A(:,1) < 1.6);
Result = A(p,:);
scatter3(Result(:,1), Result(:,2), Result(:,3))
hold on
if ~isempty(Result) %// Change here
z = [z; Result(1) Result(2) Result(3)]; %// Change
end
end
subplot(2,1,2)
surf(z)
What's important is the initialization of z. I made this empty, and we only add to z if Result is not empty - this will happen if you generate a number that is not between 1.1 and 1.6.

Matlab : x v/s y plot

I want to plot a function y=1-exp(c) ,where as the range of x is defined. The plot is to be between x and the function y. The plot just shows just 1 point instead of showing a series of points exponentially.I am new in Matlab.Sp,please help me where I am going wrong Here is the code:
for x = -10:0.25:10
if(x>0)
c=-6*x;
m=exp(c);
y = 1-m
end
plot(x,y,'o')
xlabel('x')
ylabel('y')
title('Plot')
end
This should do it:
x = -10:0.25:10; % define the x vector
c= -5*x.*(x>0); % using a logical condition the 'if' is avoided
y = 1-exp(c); % calc y given c
plot(x,y,'o')
xlabel('x')
ylabel('y')
title('Plot')
no 'for' loop or 'if' needed...
Your problem is the for loop. It is resetting the value of y and re-ploting that one point each loop. You don't need that loop at all. This code will do the trick for y = 1-exp(A*x)
Edit (2012-10-30) OP says y is zero for x<=0. #Nate's code in the answer above is probably best, but here I use logical indexing to show a different way to do the same thing.
x = -10:0.25:10; % <vector>
y = zeros(size(x)); % prealocate y with zeros and make it the same size as x
y(x>0) = 1 - exp(-5*x(x>0)); % only calculate y values for x>0
plot(x,y,'o')
xlabel('x')
ylabel('y')
title('Plot')