Amplitude of graph clips when magnified - matlab

This is the code for plotting I am using
figure
x = -pi:pi/40:pi;
plot(x,cos(5*x),'-ro',x,sin(5*x),'-.b')
hleg1 = legend('cos_x','sin_x');
The output comes like this:
When I try to stretch the time axis, what I get is like this:
But as can be seen, the amplitude gets clipped when I stretch the time axis. How do I avoid this clipping of amplitude when stretching time axis and v.V?

You can try using "Zoom In," the plus-magnifying glass icon and being very careful to select the entire vertical range of the image. To control the minimum and maximum values of the axes more precisely using the axis function.
figure
x = -pi:pi/40:pi;
plot(x,cos(5*x),'-ro',x,sin(5*x),'-.b')
hleg1 = legend('cos_x','sin_x');
axis([1.6, 3.2,-1, 1])

Related

Consistently generate line at at a specified angle as measured by user in MATLAB

Consider the simple code below that generates a straight downward sloping line in MATLAB.
clear, clc, close all
t = 0:0.1:1;
y = -t+1;
plot(t,y)
ax = gca
This is a line with slope -1, so the (acute) angle between the horizontal axis and the line is 45 degrees. Except it isn't when you measure with a protractor on your monitor.
Without changing the range of values displayed on the x and y axes or the height of the figure window, how could I ensure I would measure 45 degrees from the horizontal axis to the line if I held a protractor up to the screen?
My current approach is to change the width of the figure window. In the limit as the figure window is infinitely thin, the line x is a vertical line. Conversely, if the figure window is stretched to the edges of a monitor, it flattens out. Somewhere in the middle, the line has the angle I want. I just can't find a good way to mathematically find this point and instantiate it in code.
Edit: A slightly more generic solution for any acute angle. (I didn't test obtuse angles.)
clear, clc, close all
ang_deg = 70;
slope = tand(ang_deg);
t = 0:0.1:1;
y = -slope*t+1;
f = figure;
f.Position(3) = f.Position(3)*1.5;
plot(t,y)
% For a given height, change the width
ax = gca;
ax.Units = 'pixels';
ax.Position(3) = ax.Position(4)/slope;
You can achieve that with
axis equal
which, according to the documentation,
uses the same length for the data units along each axis.
You may want to also use
axis tight
which
fits the axes box tightly around the data by setting the axis limits equal to the range of the data
Follow up your commands with a declaration that you'll be working in pixels, and then set the width to the height:
ax.Units = 'pixels';
ax.Position(3) = ax.Position(4);

MATLAB: The exact size and position of the axis box in the case of `axis equal`?

How to know the exact size and position of the axis box (without axis labels and numbers)? For example, if I use
figure
contourf(x,y,u,100,'linestyle','none')
axis equal
set(gca,'position',[0.1,0.1,0.7,0.8]) %normalized units
The size of the axis frame/box is varyed in the case of the figure window resizing (or using axis equal), but the value of get(gca,'position') remains unchanged. For example:
figure
Z = peaks(20);
contourf(Z,10)
set(gca,'Units','pixels')
get(gca,'position')
axis equal
get(gca,'position')
ans =
0.1300 0.1100 0.7750 0.8150
after axis equal, the axis box is changed, but get(gca,'position') gives the same coordinates:
ans =
0.1300 0.1100 0.7750 0.8150
I need these to align the colorbar to the axis box (with fixed gap between them) in the case of axis equal.
When you call axis equal, the axis box aspect ratio is fixed and the Position property is treated as a maximum size. When you resize the figure window, the axis box will remain centered in the Position rectangle, but in order to maintain the same aspect ratio as before, it may not take up the entire Position rectangle.
If you want it to take up the entire Position rectangle, you can call axis equal again. (this may depend on your MATLAB version; it worked for me in R2015b).
This is also discussed in a bit more detail on MATLAB Central.
To answer your original question, it's a bit complicated. You'd have to get the plot box aspect ratio (using pbaspect() or the axes PlotBoxAspectRatio property) and figure it out:
ah = gca();
% Get the axes Position rectangle in units of pixels
old_units = get(ah,'Units');
set(ah,'Units','pixels');
pos = get(ah,'Position');
set(ah,'Units',old_units);
% Figure the PlotBox and axes Position aspect ratios
pos_aspectRatio = pos(3) / pos(4);
box_aspect = pbaspect(ah);
box_aspectRatio = box_aspect(1) / box_aspect(2);
if (box_aspectRatio > pos_aspectRatio)
% PlotBox is wider than the Position rectangle
box_height = pos(3) / box_aspectRatio;
box_dy = (pos(4)-box_height) / 2;
box_position = [pos(1), pos(2)+box_dy, pos(3), box_height];
else
% PlotBox is taller than the Position rectangle
box_width = pos(4) * box_aspectRatio;
box_dx = (pos(3)-box_width) / 2;
box_position = [pos(1)+box_dx, pos(2), box_width, pos(4)];
end
Note that this will give you the box position in pixels; if you want it in the normalized units that are the axes default, you'll need to normalize it:
fig_pos = get(get(ah,'Parent'),'Position');
box_position = box_position ./ fig_pos([3 4 3 4]);

How to detect certain moving points in a video using Matlab

I have a video of moving hose in an experiment and I need to detect certain points in that hose and calculate the amplitude of their movements, I am using the code below and I am able to extract the required point using detectSURFFeatures, the function get many unnecessary points so I am using cuba = ref_pts.selectStrongest(5); to choose only five points, the problem is I can not get a function to put a bounding box about this 5 points and get their pixel values through the video, Kindly advice what functions can be used, thanks :)
clear;
clc;
% Image aquisition from Video and converting into gray scale
vidIn = VideoReader('ItaS.mp4');
%% Load reference image, and compute surf features
ref_img = read(vidIn, 1);
ref_img_gray = rgb2gray(ref_img);
ref_pts = detectSURFFeatures(ref_img_gray);
[ref_features, ref_validPts] = extractFeatures(ref_img_gray, ref_pts);
figure; imshow(ref_img);
hold on; plot(ref_pts.selectStrongest(5));
cuba = ref_pts.selectStrongest(5);
stats1 = round(cuba.Location);
If you want to find the bounding box which covers all the five points you selected: stats1 now contains (x, y) coordinates of the selected 5 points. Find min and max for x and y coordinates. min values of x and y gives you the starting point of the rectangle. Width and height of the bounding box is now the difference of max and min in y and x directions.
If you want to extract the part of the original image inside the bounding box: just copy that part to another variable as you want. Consider the following example.
img2 = img1(y:h, x:w, :)
Here, x and y are the x and y coordinates of the top left corner of the bounding box. w and h are the width and height of the bounding box.

Wrong 3D plot in Matlab

I'm trying to create 3D plots in Matlab, and I have practically no experience. I'd really like to draw the figure described by these equations:
x = cos(u) sinh(t) / (cosh(t) - cos(u));
y = cos(u) sin(u) / (cosh(t) - cos(u));
z = sin(u);
where both u and t vary from -pi to pi. This is what Paul Bourke calls Ghost Plane.
clc
clear
a = -pi:.01:pi;
b = -pi:.01:pi;
[U,T] = meshgrid(a,b);
X = (cos(U).*sinh(T))./(cosh(T)-cos(U));
Y = (cos(U).*sin(U))./(cosh(T)-cos(U));
Z = sin(U);
figure
surf(X,Y,Z)
With the code, I get something... indescribable. How do I plot the figure?
Your code is correct. You just need to zoom in.
Some tips to make this more viewable:
Use less fine grids, by changing a = ... and b = ... to: linspace(-pi,pi,40);
Add this ,'FaceColor','none','EdgeColor','interp'); to the surf command to only plot the lines and those in color.
Add this axis equal vis3d; after the surf command, so the axis will have correct scaling and behave well while rotating.
Add whitebg('black'); and grid off; to make the background black.
Change to surf(X,Y,Z,-U,...); and add colormap('HSV'); if you want the same colors as in the original.
set(gca,'xtick',[]); set(gca,'xticklabel',[]); set(gca,'yticklabel',[]); set(gca,'ytick',[]); to remove the axis ticks
You might want to use the cameratoolbar to: Change the projection to perspective projection, zoom all the way out, move the camera in very close, to get nice perspective distortions.
VoilĂ :

How to have axes with different scales for an image in MatLab

I want to display an image with axes that has a different vertical and horizontal scale.
The following code gives me an image that is very long and thin. If I multiply the scale of the y-axis by 250 (commented line) I get the aspect ratio of the image I want but now the scale on the y-axis is wrong.
A = rand(100,400);
A_image = mat2gray(A);
A_image = imresize(A_image,2);
RI = imref2d(size(A_image),[0 800],[-1 1]);
%RI = imref2d(size(A_image),[0 800],250*[-1 1]);
figure(1);
imshow(256*A_image,RI,jet)
xlabel('$t$ (s)');
ylabel('$z$ (m)');
Changing the world reference changes the axis labels to match that world reference, but you can always change the labels back.
xlabels=get(gca,'XTickLabels'); % //this will get your current labels;
nlabels=length(xlabels); % //Get how many we need
new_xlabels=linspace(-1,1,nlabels); % //Create a linear space at each label point
set(gca,'XTickLabels',new_xlabels); % //apply the new labels