How do I prevent the legend from REALLY auto-updating

55 views (last 30 days)
I'm plotting graphs of the same type in multiple subplots, with some subplots left blank. I'd like to use the blank spots to plot a legend. I could of course move the location of the legend but that's really tedious. The seemingly obvious, clean way to do this is as in the following code. In the sixth plot region, I plot my lines, create the legend, set autoupdate to off, then set the linestyles to 'none'. Trouble is: when I set the linestyles to none, the legend autoupdates and sets the legend lines to none as well. So what I need to do is break the link between the actual lines and the legend lines.
close all;
for ii=1:2:9;
subplot(3,3,ii);
clear h;
hold on;
h(1) = plot(1:10);
h(2) = plot(10:-1:1);
if ii==5;
subplot(3,3,6);
hold on;
h(1) = plot(1:10);
h(2) = plot(10:-1:1);
legend('up','down','AutoUpdate','off');
for ii=1:numel(h);
h(ii).LineStyle='none';
end;
end;
end;
A hideous kludge is the following: close all;
for ii=1:2:9;
subplot(3,3,ii);
clear h;
hold on;
h(1) = plot(1:10);
h(2) = plot(10:-1:1);
if ii==5;
subplot(3,3,6);
hold on;
h(1) = plot(11:20);
h(2) = plot(20:30);
legend('up','down','AutoUpdate','off');
set(gca,'YLim',[1,10]);
end;
end
But this is unsatisfactory in so many ways that I won't bother to enumerate them. So the question is, is there a clean way to do what I want to do, just by breaking the link between actual plot lines and legend lines, and not resorting to a hideous kludge?
  2 Comments
dpb
dpb on 13 May 2018
The 'autoupdate' only determines whether the legend elements are added/deleted when objects are added/deleted from the axes; not whether the existing entries will/will not be kept in synch with their objects (as you've determined).
Only way I see to do something of the sort would be to use a pair of line objects specifically and only for the purpose of displaying their legend; use the form of legend for the specific handles only instead of generic for whichever are the first N lines matching the number of label strings passed.
Leo Simon
Leo Simon on 13 May 2018
I'm afraid I don't follow the suggestion. @dpb, would you mind modifying my first example to illustrate please?

Sign in to comment.

Accepted Answer

dpb
dpb on 14 May 2018
Edited: dpb on 14 May 2018
Actually, it's simpler than outlined; that kept extra lines around; don't even need that; just use the builtin feature of plot() to not show NaN values...
for ii=1:2:nSubplots
...
subplot(3,3,ii);
...
plots here
end
hAx=subplot(3,3,6); % for legend
hL(1)=plot(nan(1,1)); % create the line style; doesn't show
hL(2)=plot(nan(1,1));
hLg=legend('up','down','AutoUpdate','off');
delete(hL); % can even remove the objects
hAx.Color='none'; % just leave the legend visible
hAx.XColor='none';
hAx.YColor='none';
Salt to suit re: box outline, etc., etc., etc., ...
ADDENDUM Better way to hide the unwanted axis than zzz.Color='none' is
hAx.Visible='off';

More Answers (1)

Jan
Jan on 14 May 2018
Creating the axes object and lines only to hide them later sounds indirect and cluttered. What about setting the 'Position' of the legend directly?
figure;
for ii=1:2:9;
subplot(3,3,ii);
hold on;
h(1) = plot(1:10);
h(2) = plot(10:-1:1);
end
% Use last set of handles:
LegH = legend(h, {'up', 'down'}, 'Position', [0.7548, 0.5123, 0.1250, 0.0821]);
Of course, now the problem is how to find the needed value for the position automatically. I'd move this to an extra function, which finds the position of the subplot and uses it for moving the legend. This function will not look very smart also, but at least you do not have to create and hide graphics objects and struggle with auto-updates.
  1 Comment
Leo Simon
Leo Simon on 14 May 2018
Thanks Jan, I really don't want to have to move the legend Position (I did this in the past) for precisely the reason you indicated, but it may be a choice between bad options.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!