File Exchange

image thumbnail


version (11.6 KB) by Todd Baxter
Create an annotation that is pinned to the axes of a graph.


Updated 05 Aug 2017

View License

Annotate creates a primitive annotation object which is automatically pinned to an axes at a position specified in axes data coordinates. The initial position specified must reside within the axes limits in order for the annotation to be pinned correctly, but after creation the position may be changed to whatever is desired. Annotation placement is also supported for logarithmic axes scales and reverse axes directions. Rectangle and ellipse annotations (with only one pinned affordance) will still maintain their axes data coordinate positions after zooming, axes rescaling, etc.
The Annotate object created, essentially a wrapper for the built-in annotation object, provides access to the primitive annotation object through its 'Primitive' property which allows for further customization of the annotation itself. Also, a 'Position' property is provided which allows for setting/getting the primitive annotation object position in axes data coordinates.

A UIContextMenu is attached to the primitive annotation object which replicates the standard annotation customizations (color, line width, line style, etc.) and provides move/resize and delete functionality. The motivation being that the same annotation customization functionality could be achieved without having to enable edit plot mode. When the move/resize functionality is enabled the arrow keys can also be used to move the annotation in addition to the standard mouse button click and drag. Once enabled, clicking outside the annotation or hitting the escape key will disable the move/resize functionality.

The Annotate class provides a static method 'ButtonDownFcn' that is available to be executed as a button down callback function. It interactively creates a primitive annotation object, through a mouse button click and drag, which is automatically pinned to the axes. The property 'ParentAnnotation' is added to the primitive annotation object so its "parent annotation" Annotate object, constructed with the button down callback function, can be recovered and used to set/get the annotation position in axes data coordinates.

Annotate is HG2 compatible and also backwards compatible with HG1.

% programmatic placement through constructor
% OBJ = Annotate(AX,TYPE,X,Y)
figure; x=0:0.1:6; y=sin(x); h=plot(x,y);
obj1 = Annotate(gca, 'ellipse', [1.5,2.5], [-0.8,0.4]);
obj2 = Annotate(gca, 'arrow', [x(1),x(10)]+0.2, [y(1),y(10)]);
obj3 = Annotate(gca, 'doublearrow', [4,3], [-0.6,0.6], 'linestyle', '--');
obj4 = Annotate(gca, 'line', [1,4], [0.6,0.6], 'color', 'r');
obj4.Position = [0.5,3.5,0.8,0.8]; % set new axes data coordinate position
obj5 = Annotate(gca, 'textbox', [2.5,4.5], [0.8,0.9], 'backgroundcolor', 'none', 'string', 'example textbox');
obj5.Primitive.EdgeColor = 'none'; obj5.Primitive.FontWeight = 'bold';
obj6 = Annotate(gca, 'textarrow', [4.5,x(55)], [0.2,y(55)]); % manually input text after creation

% interactive placement through button down callback function
% Annotate.ButtonDownFcn(SRC,EVNT,TYPE)
figure; x=0:0.1:6; y=sin(x); h=plot(x,y);
set(gca, 'ButtonDownFcn', {@Annotate.ButtonDownFcn, 'textarrow', 'string', 'default text'});
set(h, 'ButtonDownFcn', {@Annotate.ButtonDownFcn, 'rectangle'}); % can be set for axes child as well
% once created with the button down callback function, a primitive annotation could be set as the current object
% and a new axes data coordinate position could be specified with the following code
% obj = get(gco,'ParentAnnotation'); obj.Position = [1 3 0.0 0.5];

% support for uipanel hierarchy and multiple axes
figure; x=0:0.1:6; y=sin(x); p0=uipanel(gcf,'position',[0,0,1,1]);
p1=uipanel(p0,'position',[0.0,0.0,0.5,1.0]); ax1=axes('parent',p1); plot(ax1,x,y,'r');
p2=uipanel(p0,'position',[0.5,0.0,0.5,1.0]); ax2=axes('parent',p2); plot(ax2,x,y,'b');
obj1 = Annotate(ax1, 'ellipse', [1.5,2.5], [-0.8,0.4]);
obj2 = Annotate(ax2, 'arrow', [x(1),x(10)]+0.2, [y(1),y(10)]);
set(ax1, 'ButtonDownFcn', {@Annotate.ButtonDownFcn, 'arrow', 'color', 'b'});
set(ax2, 'ButtonDownFcn', {@Annotate.ButtonDownFcn, 'rectangle', 'color', 'r'});

Cite As

Todd Baxter (2019). Annotate (, MATLAB Central File Exchange. Retrieved .

Comments and Ratings (5)



Oh, I solved it. Thanks for a useful tool.


how can I directly enter the string in 'textarrow' mode by the code line without using the pop-up?

Austin Fite


HG2 compatibility release along with various bug fixes and improvements

MATLAB Release Compatibility
Created with R2017a
Compatible with any release
Platform Compatibility
Windows macOS Linux