| MATLAB® | ![]() |
Some annotation object types (arrow, doublearrow, textarrow, and ellipse) are attached to figures rather than to axes. This makes it difficult to programmatically place them precisely on an axes, especially if the axes changes its position. You can, however, still locate figure-based annotations in data space by applying a transformation to their coordinates. The following example shows how to do this using a function called dsxy2figxy that transforms figure coordinates to axes coordinates for the four types of annotations listed above.
Before following the steps given below, copy the code for dsxy2figxy and save in your current directory or elsewhere on the MATLAB® path.
Create sine function data and make a line plot of it:
x1 = 1:.1:4*pi; y1 = sin(x1)./sqrt(x1); figure plot(x1,y1) axis tight
Interactively place a textarrow on the graph
Using ginput, interactively locate a textarrow annotation. Two clicks are required by ginput:
disp('Click graph to place arrow; first tail, then head:')
[axx axy] = ginput(2); % Returns list of x, list of y in data space
% Get coords in figure space; gca will be correct even for subplots
% Transform from data space to fig space
[arrowx,arrowy] = dsxy2figxy(gca, axx, axy);
har = annotation('textarrow',arrowx,arrowy);
content = sprintf('(%4.2f,%4.2f)',axx(2), axy(2));
% Plot anno text centered at the tail of the arrow
set(har,'String',content,'Fontsize',8)

Place an ellipse on the axes
To place ellipses, a coordinate box (position rectangle) is needed instead of two x-y tuples. The function dsxy2figxy computes and returns a position rectangle if it is called with one:
disp('Click in the axes to define the bounding box of an ellipse:')
[axx axy] = ginput(2); % Returns list of x, list of y in data space
abox(1) = min(axx); abox(2) = min(axy); % Get least x and y coords
abox(3) = abs(axx(1)-axx(2)); % Get box width
abox(4) = abs(axy(1)-axy(2)); % Get box height
% Get coords in figure space; gca will be correct even for subplots
[bbox] = dsxy2figxy(gca, abox); % Xform from axes to fig space
annotation('ellipse',bbox);

Here is the code for dsxy2figxy ; copy it to an M-file that can be called when you execute the example above:
function varargout = dsxy2figxy(varargin) % dsxy2figxy -- Transform point or position from axis to figure coords % Transforms [axx axy] or [xypos] from axes hAx (data) coords into coords % wrt GCF for placing annotation objects that use figure coords into data % space. The annotation objects this can be used for are % arrow, doublearrow, textarrow % ellipses (coordinates must be transformed to [x, y, width, height]) % Note that line, text, and rectangle anno objects already are placed % on a plot using axes coordinates and must be located within an axes. % Usage: Compute a position and apply to an annotation, e.g., % [axx axy] = ginput(2); % [figx figy] = getaxannopos(gca, axx, axy); % har = annotation('textarrow',figx,figy); % set(har,'String',['(' num2str(axx(2)) ',' num2str(axy(2)) ')']) %% Obtain arguments (only limited argument checking is performed). % Determine if axes handle is specified if length(varargin{1})== 1 && ishandle(varargin{1}) && ... strcmp(get(varargin{1},'type'),'axes') hAx = varargin{1}; varargin = varargin(2:end); else hAx = gca; end; % Parse either a position vector or two 2-D point tuples if length(varargin)==1 % Must be a 4-element POS vector pos = varargin{1}; else [x,y] = deal(varargin{:}); % Two tuples (start & end points) end %% Get limits axun = get(hAx,'Units'); set(hAx,'Units','normalized'); % Need normaized units to do the xform axpos = get(hAx,'Position'); axlim = axis(hAx); % Get the axis limits [xlim ylim (zlim)] axwidth = diff(axlim(1:2)); axheight = diff(axlim(3:4)); %% Transform data from figure space to data space if exist('x','var') % Transform a and return pair of points varargout{1} = (x-axlim(1))*axpos(3)/axwidth + axpos(1); varargout{2} = (y-axlim(3))*axpos(4)/axheight + axpos(2); else % Transform and return a position rectangle pos(1) = (pos(1)-axlim(1))/axwidth*axpos(3) + axpos(1); pos(2) = (pos(2)-axlim(3))/axheight*axpos(4) + axpos(2); pos(3) = pos(3)*axpos(3)/axwidth; pos(4) = pos(4)*axpos(4)/axheight; varargout{1} = pos; end %% Restore axes units set(hAx,'Units',axun)
![]() | Adding Arrows and Lines to Graphs | Basic Plotting Commands | ![]() |
| © 1984-2008- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |