I am using impoly as in the script below and I have two questions:
Can I limit the to points clicked (e.g., 5) and close it automatically?
Is there a way convert the impoly to imrect like in the attached image (red box)?
Script:
clc;
clear;
figure, imshow('pout.tif');
hpoly = impoly(gca);
From the documentation of impoly, I don't think it is directly possible. For such custom behaviour, you should probably write your own point picking function.
Several matlab functio ncan help you in this direction.
[x,y] = ginput(n) to pick points
impoint(hparent,x, y) to draw draggable points,
line to draw a the line between points, and the rectangle bounding box.
impoint has a 'PositionConstraintFcn' parameter, that will call a function of yours when the point is moved. You can use it to update the lines draw when the points are moved.
I suggest you to have a main function that handles the point picking (constraining the number of points, etc...), and a "display" function, that calculate the bounding box, draw the lines between points, that you can call when a point is added (in the main function), or when a point is moved (with the 'PositionConstraintFcn'parameter).
When determining points within polygons using MATLAB's inpolygon function, I find that the results are exactly correct for polygons drawn on linear axes but only approximately correct for polygons drawn on log-scale axes. Although my suspicions lean in favor of a MATLAB bug, it's possible I've overlooked something.
The following code reproduces the issue I have been experiencing with other data. The results are shown in the following image (the bottom set of panels are zoomed views of the top panels). One can appreciate that there are unlabeled points inside the polygon and labeled points outside the polygon, neither of which should occur, in the case of a polygon drawn on log-scale axes (right). In contrast, the polygon test is exact for polygons drawn on linear axes (left).
n=2E4;
x(:,1)=rand(n,1); y(:,1)=rand(n,1);
x(:,2)=lognrnd(0.5,0.25,n,1); y(:,2)=lognrnd(0.5,0.25,n,1);
for m=1:2
subplot(1,2,m);
scatter(x(:,m),y(:,m),'.'); hold on;
if(m==2)
set(gca,'xscale','log'); set(gca,'yscale','log');
end
p=impoly(gca);
pc=getPosition(p);
in=inpolygon(x(:,m),y(:,m),pc(:,1),pc(:,2));
scatter(x(in,m),y(in,m),20);
end
I think you missed something: A line in normal scale is not a line in log scale. Your polygons are not properly drawn in the log scale, as you draw 2 points and put them together with a straight line.
Look at the real polygon in log space:
close all
clear
n=2e4;
x(:,1)=rand(n,1); y(:,1)=rand(n,1);
x(:,2)=lognrnd(0.5,0.25,n,1); y(:,2)=lognrnd(0.5,0.25,n,1);
for m=1:2
subplot(1,2,m);
scatter(x(:,m),y(:,m),'.'); hold on;
if(m==2)
set(gca,'xscale','log'); set(gca,'yscale','log');
end
p=impoly(gca);
pc=getPosition(p);
% plot polygon
hold on
for ii=1:size(pc,1)-1
plot(linspace(pc(ii,1),pc(ii+1,1),100),linspace(pc(ii,2),pc(ii+1,2),100),'g')
end
plot(linspace(pc(end,1),pc(1,1),100),linspace(pc(end,2),pc(1,2),100),'g')
in=inpolygon(x(:,m),y(:,m),pc(:,1),pc(:,2));
scatter(x(in,m),y(in,m),20);
end
Look at this zoomed in result (click to enlarge):
This happens because the polygon is defined in euclidean space, and it is defined as points linked by lines. If you want to work in log space, things may get complicated. One way to numerically approximate it is the inverse of what I did for plotting. Create dense enough sampled straight line on log space, convert it to linear space, and define a high vertex polygon with the resulting points. Then use inpolygon.
I am trying to draw an arbitrary line on a figure in matlab (off of a plot) and I don't know what command I can use.
I tried using the arrow package, but I'm getting bad results
You can use the line function and set the clipping property to off to draw a line that is visible outside the axis. The x and y coordinates of line will be in the coordinates of the axis and you may need to change the axis limits.
I've changed the look of my plots, and now the line of the plots accidentally goes under the X-axis. The problem looks like this (notice the black lines under the axis):
How can I get rid of it? I've change the plot line like this:
aaplPlot.interpolation = CPTScatterPlotInterpolationCurved;
Plots do not draw outside the plot area. You can control its size by setting padding on the plot area frame to push the edges of the plot area inwards. You will also need to adjust the plot ranges of the plot space to keep the same appearance.
In matlab I need to create a mesh (surf) of a function.
then I need to show the mesh contour lines.
in the end I need to show with arrows the contour lines direction.
I have this so far:
mesh(T); //T is the matrix [150x200] created by the function, this present me the mesh
contour(T);//this present me the contour lines
[px py]=gradient(T);//this for calculate gradient of T (px is[150x200] and also py)
contour(T), hold on, quiver(px,py), hold off //quiver is to make arrows
This work fine, I can see the contour lines but my problem is that the arrows are too crowded and what i'm seeing it not very clear.
I need to diluted px and py but I don't know how.
I don't know if it is something I need to do before the gradient function or after.
I need that px and py will stay on [150x200] and maybe replace some value in them to zero,
Thank you all!
I'd "dilute" the arrow, (px,py) by sampling just a subset of them. For example:
N=25; % or usea different # of points if needed
range1=unique(round(linspace(1,size(T,1),N)));
range2=unique(round(linspace(1,size(T,1),N)));
[rx ry]=meshgrid(range1,range2);
quiver(rx,ry,px(range1,range2),py(range1,range2)); %, hold off