Conflict between "TextLocation" and "annotation" when using "Legend"

10 views (last 30 days)
Sim
Sim on 9 Feb 2022
Edited: Sim on 9 Feb 2022
Hi, I would like to use the position retrieved with the function TextLocation (by MathWorks Support Team) and use it for the annotation position.
However, when I do so the legend text in the subplot (2,2) takes the text of the annotation. How to solve this thing?
% input
x = -10:10;
city = {'London', 'Paris', 'Berlin','Madrid'};
season = {'summer','winter'};
colors = {'blue','red','black','magenta'};
% my plot (using "subaxis")
figure
for i = 1 : 4
subaxis(2,2,i);
y1 = (rand(1,21)-0.5)*20;
y2 = (rand(1,21)-0.5)*10;
hold on
p1(i) = plot(x, y1, 'Color', colors{i}, 'LineStyle','--');
p2(i) = plot(x, y2, 'Color', colors{i}, 'LineStyle','-');
hold off
p1(i).DisplayName = [city{i} ', ' season{1}];
p2(i).DisplayName = [city{i} ', ' season{2}];
legend % <-- "legend" here to see the legend text in the subplots
end
% annotation
str1 = 'further information';
str2 = sprintf('annotation: %s', str1);
% use the "TextLocation" position for "annotation"
mytext = TextLocation(str2,'Location','southeast');
dim = mytext.Position;
delete(mytext)
annotation('textbox',dim,'String',str2,'FitBoxToText','on');
% again "legend" here below to see the legend text in the subplot (2,2)
% since the legend text disappears in that subplot when using "TextLocation"
legend

Accepted Answer

DGM
DGM on 9 Feb 2022
Edited: DGM on 9 Feb 2022
Oof I didn't notice what was going on. When TextLocation.m creates the temporary legend object to scrape geometry from, it sets the DisplayName property of the first plot object in the axes. So you have to run TextLocation before creating the legend and before setting the DisplayName properties.
% input
x = -10:10;
city = {'London', 'Paris', 'Berlin','Madrid'};
season = {'summer','winter'};
colors = {'blue','red','black','magenta'};
% my plot (using "subaxis")
for i = 1 : 4
subaxis(2,2,i);
y1 = (rand(1,21)-0.5)*20;
y2 = (rand(1,21)-0.5)*10;
hold on
p1(i) = plot(x, y1, 'Color', colors{i}, 'LineStyle','--');
p2(i) = plot(x, y2, 'Color', colors{i}, 'LineStyle','-');
hold off
p1(i).DisplayName = [city{i} ', ' season{1}];
p2(i).DisplayName = [city{i} ', ' season{2}];
legend % <-- "legend" here to see the legend text in the subplots
end
% annotation
str1 = 'further information';
str2 = sprintf('annotation: %s', str1);
mytext = TextLocation(str2,'Location','southeast');
set(mytext,'String',str2,'FitBoxToText','on','linestyle','-');
p1(i).DisplayName = [city{i} ', ' season{1}]; % fix the DisplayName
legend
Either that or conditionally create the annotation inside the loop before the last legend is created.
It's not part of the problem, but note that I made this simplification:
Instead of doing this unnecessary duplication:
mytext = TextLocation(str2,'Location','southeast'); % < -- this is a textbox annotation
dim = mytext.Position;
delete(mytext) % you delete it
annotation('textbox',dim,'String',str2,'FitBoxToText','on'); % and then remake it again
Just set the properties of the annotation you already have.
mytext = TextLocation(str2,'Location','southeast');
set(mytext,'String',str2,'FitBoxToText','on','linestyle','-');
Either that, or you could just open TextLocation and tailor its default behavior to your tastes.
  1 Comment
Sim
Sim on 9 Feb 2022
Many thanks @DGM for having solved my messy code!
I am going to use your simplification!
:-)

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!