Drawing circles around points in a plot - matlab

I have two matrices
timeline = [0.0008 0.0012 0.0016 0.0020 0.0024 0.0028];
Origdata =
79.8400 69.9390 50.0410 55.5082 34.5200 37.4486 31.4237 27.3532 23.2860 19.3039
79.7600 69.8193 49.8822 55.3115 34.2800 37.1730 31.1044 26.9942 22.8876 18.9061
79.6800 69.6996 49.7233 55.1148 34.0400 36.8975 30.7850 26.6352 22.4891 18.5084
79.6000 69.5799 49.5645 54.9181 33.8000 36.6221 30.4657 26.2762 22.0907 18.1108
79.5200 69.4602 49.4057 54.7215 33.5600 36.3467 30.1464 25.9173 21.6924 17.7133
79.4400 69.3405 49.2469 54.5249 33.3200 36.0714 29.8271 25.5584 21.2941 17.3159
When I plot them, I get a graph like below.
plot(timeline, Origdata, '.');
How can I draw a circle of radius 0.3524 value around each point? This radius should be relative to the y-axis only.

You can do this easily using viscircles (which requires the Image Processing Toolbox) however I don't think that the output is actually what you're expecting.
radius = 0.3524;
dots = plot(timeline, Origdata, '.');
hold on
for k = 1:numel(dots)
plotdata = get(dots(k));
centers = [plotdata.XData(:), plotdata.YData(:)];
% Ensure the the colors match the original plot
color = get(dots(k), 'Color');
viscircles(centers, radius * ones(size(centers(:,1))), 'Color', color);
end
The reason that it looks like this is because your X data is very close together relative to your y data and for circles to appear as circles, I have forced the x and y scaling of the axes to be equal (axis equal)
Edit
If you only want the radius to be relative to the y axis (distance) then we actually need to draw ellipses with an x and y radius. We want to scale the "x-radius" to make it appear as a circle regardless of your true axes aspect ratio, something like this can actually do that.
The trick to the code below is setting the data and plot aspect ratios (pbaspect and daspect) to manual. This ensures that the aspect ratio of the axes doesn't change during zoom, resizing, etc and makes sure that our "circles" remain circular-looking.
dots = plot(timeline, Origdata, '.');
drawnow
% Force the aspect ratio to not change (keep the circles, as circles)
pbaspect('manual')
daspect('manual')
hold on
aspectRatio = daspect;
t = linspace(0, 2*pi, 100);
t(end+1) = NaN;
radius = 4.3524;
% Scale the radii for each axis
yradius = radius;
xradius = radius * aspectRatio(1)/aspectRatio(2);
% Create a circle "template" with a trailing NaN to disconnect consecutive circles
t = linspace(0, 2*pi, 100);
t(end+1) = NaN;
circle = [xradius*cos(t(:)), yradius*sin(t(:))];
for k = 1:numel(dots)
x = get(dots(k), 'XData');
y = get(dots(k), 'YData');
color = get(dots(k), 'Color');
% Center circle template at all points
circles = arrayfun(#(x,y)bsxfun(#plus, [x,y], circle), x, y, 'uni', 0);
circles = cat(1, circles{:});
plot(circles(:,1), circles(:,2), 'Color', color)
end
Just to demonstrate, if we increase the circle radius to 4.3524 we can see the circles better.
And this works with all resizing etc.

To draw circles in MATLAB, you obviously have to use the rectangle function ;)
As mentioned in my comment, the size of 0.3524 does not match your axis, so I chose different sizes to have the circles actually visible, These are rx and ry
timeline = [0.0008 0.0012 0.0016 0.0020 0.0024 0.0028];
Orgidata =[79.8400 69.9390 50.0410 55.5082 34.5200 37.4486 31.4237 27.3532 23.2860 19.3039
79.7600 69.8193 49.8822 55.3115 34.2800 37.1730 31.1044 26.9942 22.8876 18.9061
79.6800 69.6996 49.7233 55.1148 34.0400 36.8975 30.7850 26.6352 22.4891 18.5084
79.6000 69.5799 49.5645 54.9181 33.8000 36.6221 30.4657 26.2762 22.0907 18.1108
79.5200 69.4602 49.4057 54.7215 33.5600 36.3467 30.1464 25.9173 21.6924 17.7133
79.4400 69.3405 49.2469 54.5249 33.3200 36.0714 29.8271 25.5584 21.2941 17.3159];
ry=1;
rx=0.0001;
dots=plot(timeline, Orgidata , '.');
hold on
for ix=1:size(Orgidata ,1)
for jx=1:size(Orgidata ,2)
rectangle('Position',[timeline(ix)-(rx/2),Orgidata(ix,jx)-(ry/2),rx,ry],'Curvature',[1,1],'EdgeColor',get(dots(jx), 'Color'));
end
end

Related

Estimating an ellipse with a multi-variate Gaussian

In MATLAB, say I have the parameters for an ellipse:
(x,y) center
Minor axis radius
Major axis radius
Angle of rotation
Now, I want to generate random points that lie within that ellipse, approximated from a 2D gaussian.
My attempt thus far is this:
num_samps = 100;
data = [randn(num_samps, 1)+x_center randn(num_samps, 1)+y_center];
This gives me a cluster of data that's approximately centered at the center, however if I draw the ellipse over the top some of the points might still be outside.
How do I enforce the axis rules and the rotation?
Thanks.
my assumptions
x_center = h
y_center = k
Minor Axis Radius = b
Major Axis Raduis = a
rotation angle = alpha
h=0;
k=0;
b=5;
a=10;
alpha=30;
num_samps = 100;
data = [randn(num_samps, 1)+h randn(num_samps, 1)+k];
chk=(((((data(:,1)-h).*cos(alpha)+(data(:,2)-k).*sin(alpha))./a).^2) +...
(((data(:,1)-h).*sin(alpha)+(data(:,2)-k).*cos(alpha))./b).^2)<=1;
idx=find(chk==0);
if ~isempty(idx)
data(idx,:)=data(idx,:)-.5*ones(length(idx),2);
end

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 translate a point on a circle?

I am trying to create a circle from the given radius and translate the circle.
edia = 10; %diameter
theta=linspace(0,2*pi, 100); %100 evenly spaced points.
radius = edia./2;
x = radius.*cos(theta);
y = radius.*sin(theta);
plot(x,y, 'k')
axis equal
axis([-edia, edia, -edia, edia]);
After creating a circle using the code, I have to translate it but I have no idea how to do it.
This is the circle that I have
and this is what I am suppose to get after translating
Thank you.
for this simple case, just add the shift directly.
close all
edia = 10; %diameter
theta=linspace(0,2*pi, 100); %100 evenly spaced points.
radius = edia./2;
x = radius.*cos(theta);
y = radius.*sin(theta);
plot(x,y, 'k')
axis equal
axis([-edia, edia, -edia, edia]);
newX=3; newY=4;
hold on;
plot(x+newX,y+newY, '-.')

Fill area between concentric circles in matlab

I have pairs of concentric circles. I want to fill area btween these concentric circles in matlab. I am trying "fill" function...but it is filling the outre circle completely.
Here's a way using patch:
t = linspace(0,2*pi);
x0=1; y0=3; % circles center
rin = 0.4; rout = 0.6; % radii sizes
patch([x0+rout*cos(t),x0+rin*cos(t)],[y0+rout*sin(t),y0+rin*sin(t)],'r','linestyle','none');

How to get coordinates of corners of an image in matlab

I want to get the four corner points or coordinates of an image. How can get I get them in MatLab?
If you are referring to the coordinates of the image corners when you plot the image in an axes using either IMSHOW or IMAGE/IMAGESC, then here is how you can find them:
If you plot the image without specifying ranges:
image(img);
imshow(img);
Then img is plotted on an axes with the pixels centered at the values 1:size(img,2) horizontally and 1:size(img,1) vertically. Since these values represent the pixel centers, and the pixel size is 1, then the image extends half a pixel past the above ranges in every direction. The extents of the image are therefore:
xmin = 0.5;
xmax = size(img,2)+0.5;
ymin = 0.5;
ymax = size(img,1)+0.5;
From which you can get your corner coordinates [xmin ymin], [xmin ymax], [xmax ymin], and [xmax ymax].
If you specify ranges for plotting, such as:
image([x1 x2],[y1 y2],img);
You may think that these limits you specify are the edges of the plotted image, but they are actually the extents of the pixel centers, so yet again the true extent of the plotted image is half a pixel further in every direction. The pixel size in each direction can be calculated as follows:
dx = abs(x2-x1)/size(img,2);
dy = abs(y2-y1)/size(img,1);
And the extents of the image are therefore:
xmin = min(x1,x2)-0.5*dx;
xmax = max(x1,x2)+0.5*dx;
ymin = min(y1,y2)-0.5*dy;
ymax = max(y1,y2)+0.5*dy;
From which you can again easily get your corner coordinates.