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.
Related
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).
I've been trying to use the MATLAB 'area' plotting function (filled line plot) however when I plot with a log y-scale, the plot is just a line with no "fill". Am I missing something here?
My guess is that the y-coordinates of your area are very big. If you have a look to the log function, the values above 1 are heavily shrunk.
Thus, the y-side of your area goes from a segment to a point. If you try to zoom a lot in the y-axis, you may see the area as a rectangle instead of a line.
Simple rounded corner rectangle code in Matlab can be written as follows.
rectangle('Position',[0,-1.37/2,3.75,1.37],...
'Curvature',[1],...
'LineWidth',1,'LineStyle','-')
daspect([1,1,1])
How to get the x and y coordinates arrays of this figure?
To get the axes units boundaries, do:
axisUnits = axis(axesHandle) % axesHandle could be gca
axisUnits will be an four elements array, with the following syntax: [xlowlim xhighlim ylowlim yhighlim], it will also contain the zlow and zhigh for 3-D plots.
But I think that is not what you need to know. Checking the matlab documentation for the rectangle properties, we find:
Position four-element vector [x,y,width,height]
Location and size of rectangle. Specifies the location and size of the
rectangle in the data units of the axes. The point defined by x, y
specifies one corner of the rectangle, and width and height define the
size in units along the x- and y-axes respectively.
It is also documented on the rectangle documentation:
rectangle('Position',[x,y,w,h]) draws the rectangle from the point x,y
and having a width of w and a height of h. Specify values in axes data
units.
See if this illustrate what you want. You have an x axis that goes from −100 to 100 and y axis that goes from 5 to 15. Suppose you want to put a rectangle from −30 to −20 in x and 8 to 10 in y.
rectangle('Position',[-30,8,10,2]);
As explained by the comments there appears to be no direct way to query the figure created by rectangle and extract x/y coordinates. On the other hand, I can think of two simple strategies to arrive at coordinates that will closely reproduce the curve generated with rectangle:
(1) Save the figure as an image (say .png) and process the image to extract points corresponding to the curve. Some degree of massaging is necessary but this is relatively straightforward if blunt and I expect the code to be somewhat slow at execution compared to getting data from an axes object.
(2) Write your own code to draw a rectangle with curved edges. While recreating precisely what matlab draws may not be so simple, you may be satisfied with your own version.
Whether you choose one of these approaches boils down to (a) what speed of execution you consider acceptable (b) how closely you need to replicate what rectangle draws on screen (c) whether you have image processing routines, say for reading an image file.
Edit
If you have the image processing toolbox you can arrive at a set of points representing the rectangle as follows:
h=rectangle('Position',[0,-1.37/2,3.75,1.37],...
'Curvature',[1],...
'LineWidth',1,'LineStyle','-')
daspect([1,1,1])
axis off
saveas(gca,'test.png');
im = imread('test.png');
im = rgb2gray(im);
figure, imshow(im)
Note that you will still need to apply a threshold to pick the relevant points from the image and then transform the coordinate system and rearrange the points in order to display properly as a connected set. You'll probably also want to tinker with resolution of the initial image file or apply image processing functions to get a smooth curve.
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.
I have a script that plots a Fourier series using stem(). I know that I can fill the circle at the end of the stems with stem( , 'fill'). However I would like it to only fill the circle if the magnitude is negative, or alternatively, fill all of them, but have an outer circle of another color on those that have a negative magnitude.
I tried using a variable inside stem(), and also a full if-else statement, but both returned errors.
Any way this can be done?
You can remove marker from stem plot with 'Marker' property set to 'none'. Then add markers where ever you like with plot or scatter function. Add hold on after the stem command and hold off after all plotting commands.
For example:
x = randn(20,1);
stem(x,'Marker','none')
hold on
plot(find(x>0),x(x>0),'ro')
plot(find(x<0),x(x<0),'bx')
hold off