Save an annotation onto a figure programmatically in app designer

16 views (last 30 days)
I have a modelling app which I use to show effects of noise on solitons.
The graph loads/saves/edits fine. The "Create Info Panel" also works...
BUT...
I cannot save the annotation panel on the figure. If I load a figure into MATLAB directly and use the property inspector to create an annotation then I can save it as *.fig and it saves the annotation which then loads.
I have examined everything from groot; figure; axes... to look for where the annotation is linked to the figure but simply cannot find it. In my code the axis and children are copied to the panel and the annotation is attached to the panel through
app.tbx = annotation(app.GraphViewPanel,'textbox',...
[app.XSpinner.Value app.YSpinner.Value app.WSpinner.Value app.HSpinner.Value], ...
'Interpreter','latex');
set(app.tbx,'string',str);
set(app.tbx,'FontSize',app.HSpinner_2.Value);
The graph is created by
app.Figure2Edit = openfig(app.NameTemp, 'invisible');
...
ax_to_copy = app.Figure2Edit.Children;
app.ax = copyobj(ax_to_copy,app.GraphViewPanel);
If you remove invisible then the created in MATLAB annotation shows up on the MATLAB figure but not on my panel. Clearly the annotation is not a child object of the figure so where is it stored/associated/kept. The irony is that I can find a reference to a text object in the MATLAB version immediately above but only if it is active as shown.
close all; format compact;
file = 'U_L250run5P_Avg.fig';
f_new = openfig(file);
ax = findobj(f_new)
gives the figure above and
ax =
8×1 graphics array:
Figure (1)
UIAxes
Line
Line
Line
Line
Line
Line
ax(1) gives the figure and its properties and nothing helpful, Children: [1×1 UIAxes] shows no sign of the two lines of text in the annotation. Clicking on the "edit Plot" arrow and rerunning ax(1) now shows
CurrentObject: [1×1 TextBox]
whereas befor highlighting it showed
CurrentObject: [0×0 GraphicsPlaceholder]
Until I know where in the hierarchy of objects the annotation belongs and how it fits in to the figures that MATLAB saves, I am stuck with editting and saving these figures. They do not copy though I can use snipping tool but that means I have to recreate the same figure each time as I cannot save and load it. A map would be wonderful!!
  1 Comment
Fangjun Jiang
Fangjun Jiang on 7 Mar 2024
annotation(container,___) creates the annotation in the figure, uipanel, or uitab specified by container, instead of in the current figure.
text(ax,___) creates the text in the Cartesian, polar, or geographic axes specified by ax instead of in the current axes (gca). The option ax can precede any of the input argument combinations in the previous syntaxes.

Sign in to comment.

Accepted Answer

Voss
Voss on 7 Mar 2024
Annotations are children of an annotation pane which has HandleVisibility 'off' by default, so it doesn't show up in the parent container's Children property. That's why the annotations are not copied when you do copyobj(fig.Children,_).
% create a figure
f = figure('Visible','off'); % invisible just to avoid it taking up space here
% create an annotation
a = annotation(f,'textbox');
% annotations are children of an AnnotationPane
a.Parent
ans =
AnnotationPane
% which has HandleVisibility 'off' by default
a.Parent.HandleVisibility
ans = 'off'
% so it doesn't show up in the parent container's Children property
f.Children
ans =
0×0 empty GraphicsPlaceholder array.
If you were to set the annotation pane's HandleVisibility to 'on' then it would show up in the Children.
a.Parent.HandleVisibility = 'on';
f.Children
ans =
AnnotationPane
You can use findall to find all annotations in a figure or panel.
% create a figure
f = figure('Visible','off'); % invisible just to avoid it taking up space here
% create an annotation
a = annotation(f,'textbox');
% children shows nothing
f.Children
ans =
0×0 empty GraphicsPlaceholder array.
% findall finds two annotation panes
ap = findall(f,'Type','annotationpane')
ap =
2×1 AnnotationPane array: AnnotationPane AnnotationPane
% the first one contains the annotation
ap(1).Children
ans =
TextBox with properties: String: {''} FontName: 'Helvetica' FontSize: 10 FontWeight: 'normal' Color: [0 0 0] BackgroundColor: 'none' EdgeColor: [0 0 0] LineStyle: '-' LineWidth: 0.5000 Position: [0.3000 0.3000 0.1000 0.1000] Units: 'normalized' Use GET to show all properties
% the second one contains nothing
ap(2).Children
ans =
0×0 empty GraphicsPlaceholder array.
And then either set their HandleVisiblity to 'on' and copy all the Children like you are already doing (then maybe set the HandleVisiblity back 'off' for the originals and the copies), or copy the annotation pane(s) separately.
  2 Comments
Jo Wharrier
Jo Wharrier on 8 Mar 2024
I enjoyed your answer immensely as it made me smile. It is always good to be reminded that one is fallable especially at my age (72!?). I have met the 'Handle Visibility - off' issue before but it did not occur to me that between the annotation and the figure was another object. Having read your answer, the whole thing is completely clear and the answer is obvious. It always is in hindsight - that latter is a marvellous skill!
So, great answer. Problem completely solved for which I am very grateful.
Tx
Jo

Sign in to comment.

More Answers (0)

Categories

Find more on Creating, Deleting, and Querying Graphics Objects in Help Center and File Exchange

Products


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!