Add lines of different lengths to plot in Matlab - matlab

In this trivial example I extract a portion of x to make y & y1. To plot y1 in the correct position I used NaN padding in the front. I'm wondering whether NaN padding is considered the best practice or is there some way to directly specify the X coordinate where I want the y1 line segment plotted?
figure(500);
hold off;
x = rand(1,100);
plot(x);
y = x(20:60)+3;
hold on;
plot(y);
y1 = horzcat(repmat(nan,1,19), (y+3));
plot(y1);

If your main goal is just to display the sub-set of data within the proper range, seems like you could just specify the x-range directly, like:
x_range = 20:60;
y = x(x_range)+3;
hold on;
plot(y);
plot(x_range, y+3);
grid on
Which gives the identical result you got using Nans:

Related

MATLAB: function point_cloud

Question:
Write a function called point_cloud that takes one scalar as an input argument (the function does not have to check the format of the input) and has no output argument.
If it is called like this, point_cloud(100), then it plots 100 points. Each point has a random x coordinate and a random y coordinate, each of which is gotten by a call to randn, which uses a normal distribution with a standard deviation equal to 1. The range of the plot axes should be −5 to 5 in both the x and y dimensions. The grid should be turned off. The points should be plotted and displayed one at a time by calling plot with only one point specified and, following the call of plot, by a call of drawnow, which causes the point to be plotted immediately. The command hold on should be included so that all previous points are retained when a new point is plotted.
Figure 2.41 shows an example view of the plot after point_cloud(100000) has completed its point-by-point plotting on a Mac. (Note that on Windows the points are much larger. Also note that it takes a long time to plot this many points with drawnow. Finally, try zooming in the middle.)
Figure 2.41
My Code:
function point_cloud(N)
hold on
grid off
axis([-5,5,-5,5])
for ii = 1:N
plot(randn(ii));
drawnow;
end
I know this is wrong, but I'm not sure how to solve this problem. Can someone help?
Solved code:
function point_cloud(N)
figure
hold on
grid off
axis([-5,5,-5,5])
x = randn(N,1);
y = randn(N,1);
for ii = 1:N
plot(x(ii),y(ii),'b.');
drawnow;
end
You do not need the for loop at all. And drawing the plot each iteration is very time consuming. How about rather using the scatter function.
figure
hold on
grid off
axis([-5,5,-5,5])
x = randn(N,1);
y = randn(N,1);
scatter(x,y,'b.')
This will be a lot faster.
To add to the other answer, here is the code as a function, with the added functionality that the points are one pixel on Windows as well:
function point_cloud(N)
f = figure;
x = randn(N,1);
y = randn(N,1);
scatter(x,y,1/36,'b.');
f.GraphicsSmoothing = 'off';
grid off
axis([-5,5,-5,5])
axis equal
end
The size of the markers is set with the third parameter of scatter: 1/36. The graphics smoothing of the figure needs to be set to 'off' as well, to make sure that the pixels don't become blurry or lighter.
Here's a 3D version:
function point_cloud3D(N)
f = figure;
x = randn(N,1);
y = randn(N,1);
z = randn(N,1);
scatter3(x,y,z,1/36,'b.');
f.GraphicsSmoothing = 'off';
grid off
axis([-5,5,-5,5,-5,5])
axis square
view(3)
end

Plot gradient in matlab and nothing but blank appears

I'm trying to plot the gradient of the real part of a complex function, however what I get is a blank figure. I do not understand what I am doing wrong since the code works with other functions (such as the imaginary part)
% Set up
x = -3:0.2:3;
y1 = (-3:0.2:3);
y = (-3:0.2:3)*1i;
[X, Y]= meshgrid(x,y);
% Complex variable s
s = X + Y;
% Complex function f(z)
z = s + 1./s;
figure
subplot(1,2,1);
[Dx, Dy] = gradient(real(z),.2,.5);
quiver(x,y1,Dx,Dy)
title('u(x,y) gradient, vector field');
%%Imaginary part
subplot(1,2,2)
contour(x,y1,imag(z),linspace(-10,10,100)); title('Contour of Im(f)');
xlabel('x'); ylabel('y'); %clabel(C3);
title('Imaginary part');
Here below is the image I get
I tried to rescale and resize the picture, the domain etc... but couldn't get the gradient to display (the arrows). What am I doing wrong here?
EDIT:
I found out it displays blank perhaps because there are some Inf and -Inf values in the Dy and Dx variables, is there an option to ignore these values or set them to 0?
It looks to me like it works, but the line width of your arrows is too small for you to see.
You can increase it by assigning a handle to the quiver plot like so:
hQuiver = quiver(x,y1,Dx,Dy);
And then, after the plot is created, change any of its many properties like so:
set(hQuiver,'LineWidth',4)
or do it all in the call to quiver:
hQuiver = quiver(x,y1,Dx,Dy,'LineWidth',4);
In this case it gives the following:
EDIT:
To answer your secondary question, you can set elements that are equal to +Inf or -Inf to any value you want using isinf:
Dx(isinf(Dx)) = 0;
and
Dy(isinf(Dy)) = 0;
It is not blank. You've plotted the quiver diagram (usually used in optical flow diagrams). It is giving an inward pointing arrow at each of the locations formed by the grid with points in x and y1.

matlab find line interception and represent it

For this given example:
a=rand(100,1)
ecdf(a)
The obtained plot will have on x proportion of bin values, and on y the proportion of points. I wanted to add a line y=0.5 (50% percent of values) and when cross the line in the plot gather and shows the predicted x value.
It is possible but it suppresses my knowledge.
Thanks in advance
Not sure I interpret your question correctly - but could it be as simple as
a=rand(100,1)
ecdf(a)
hold on
plot([0 1],[1 1]*0.5);
This adds a line at a height of 0.5 from 0 to 1 (which I believe are the limits of the plot that ecdf produced for you).
If you want to find the point where these two lines intersect, you need to obtain the points in the plot using a different form of the ecdf function:
a = rand(100,1)
[f x] = ecdf(a);
figure
plot(x, f); % now you have to make the plot yourself...
hold all
plot(x, 0.5 * ones(size(x))); % add the line at y=0.5
title 'cumulative probability of rand()'
xest = interp1(f, x, 0.5); % interpolate - find x where f would be 0.5
fprintf(1, 'The intercept is at x=%.2f\n", xest);

draw a line of best fit through data with shaded region for error

I have the following data:
dat = [9.3,0.6,0.4,0.7;...
3.2,1.2,0.7,1.9;...
3.9,1.8,0.7,1.9;...
1.0,7.4,5.6,10.7;...
4.7,1.0,0.5,1.3;...
2.2,2.6,1.2,2.7;...
7.2,1.0,0.5,1.1;...
1.0,4.8,7.5,10.3;...
2.7,1.8,1.7,4.0;...
8.2,0.8,0.4,0.9;...
1.0,4.9,5.7,8.2;...
12.9,1.3,0.6,1.6;...
7.7,0.8,0.5,1.3;...
5.8,0.9,0.6,1.9;...
1.1,4.5,6.2,12.1;...
1.1,4.5,2.8,4.8;...
16.4,0.3,0.3,0.5;...
10.4,0.6,0.3,0.7;...
2.2,3.1,2.2,4.6];
where the first column shows the observed values the second column shows the modeled values and the third and fourth columns show the min and max respectively.
I can plot the relationship between observed and modeled by
scatter(d(:,1),d(:,2))
Next, I would like to draw a smooth line through these points to show the relationship. How can this be done? Obviously a simple straight line would not be much use here.
Secondly, I would like to use the min and max (3rd and 4th columns respectively) to draw a shaded region around the modeled values in order to show the associated error.
I would eventually like to have something that looks like
http://www.giss.nasa.gov/research/briefs/rosenzweig_03/figure2.gif
Something like this?
%// Rename and sort your data
[x,I] = sort(dat(:,1));
y = dat(I,2);
mins = dat(I,3);
maxs = dat(I,4);
%// Assume a model of the form y = A + B/x. Solve for A and B
%// using least squares
P = [ones(size(x)) 1./x] \ y;
%// Initialize figure
figure(1), clf, hold on
set(1, 'Renderer', 'OpenGl');
%// Plot "shaded" areas
fill([x; flipud(x)], [mins; flipud(maxs)], 'y',...
'FaceAlpha', 0.2,...
'EdgeColor', 'r');
%// Plot data and fit
legendEntry(1) = plot(x, P(1) + P(2)./x, 'b',...
'LineWidth', 2);
legendEntry(2) = plot(dat(:,1), dat(:,2), 'r.',...
'Markersize', 15);

How to plot graph with customized axis

I apologize for asking this, I believe this is a simple task, but I don't know how to do it.
Suppose I have a formula y = (exp(-x) + x^2)/sqrt(pi(x) and I want to plot it as y versus x^2.
How does one do this?
Like this:
X = 0:0.1:5; %// Get the x values
x = X.^2; %// Square them
%// Your formula had errors, I fixed them but I could have misinterpreted here, please check
y = (exp(-x) + x.^2)./sqrt(pi*x); %// Calculate y at intervals based on the squared x. This is still y = f(x), I'm just calculating it at the points at which I want to plot it.
plot(x,y) %//Plot against the square X.
At this point this is no different to having just plotted it normally. What you want is to make the tickmarks go up in values of X.^2. This does not change the y-values nor distort the function, it just changes what it looks like visually. Similar to plotting against a log scale:
set(gca, 'XTick', X.^2) %//Set the tickmarks to be squared
The second method gives you a plot like
edit:
Actually I think you were asking for this:
x = 0:0.1:5;
y = x.^2; %// Put your function in here, I'm using a simple quadratic for illustrative purposes.
plot(x.^2,y) %//Plot against the square X. Now your y values a f(x^2) which is wrong, but we'll fix that later
set(gca, 'XTick', (0:0.5:5).^2) %//Set the tickmarks to be a nonlinear intervals
set(gca, 'XTickLabel', 0:0.5:5) %//Cahnge the labels to be the original x values, now accroding to the plot y = f(x) again but has the shape of f(x^2)
So here I'm plotting a simple quadratic, but if I plot it against a squared x it should become linear. However I still want to read off the graph that y=x^2, not y=x, I just want it to look like y=x. So if I read the y value for the x value of 4 on that graph i will get 16 which is still the same correct original y value.
Here's my answer: it is similar to Dan's one, but fundamentally different. You can calculate the values of y as a function of x, but plot them as a function of x^2, which is what the OP was asking, if my understanding is correct:
x = 0:0.1:5; %// Get the x values
x_squared = x.^2; %// Square them
%// Your formula had errors, I fixed them but I could have misinterpreted here, please check
y = (exp(-x) + x.^2)./sqrt(pi*x); %// Calculate y based on x, not the square of x
plot(x_squared,y) %//Plot against the square of x
As Dan mentioned, you can always change the tickmarks:
x_ticks = (0:0.5:5).^2; % coarser vector to avoid excessive number of ticks
set(gca, 'XTick', x_ticks) %//Set the tickmarks to be squared