Matlab: Combine the legends of shaded error and solid line mean

荒凉一梦 提交于 2019-12-05 09:07:33
Oleg

There is a direct general way to control legends. You can simply choose not to display line entries by fetching their 'Annotation' property and setting the 'IconDisplayStyle' to 'off'.

Also, in order to use chadsgilbert's solution, you need to collect each single patch handle from every loop iteration. I refactored your code a bit, such that it would work with both solutions.

% Refactoring you example (can be fully vectorized)
figure
axesh  = axes('next','add'); % equivalent to hold on
nZones = 4;
nPts   = 10;
clr    = {'r', 'b', 'g', 'm', 'y', 'c'};
X      = randi(10, nPts, nZones);
Y      = randi(10, nPts, nZones);
XError = rand(nPts, nZones);

% Preallocate handles 
hl = zeros(nZones,1);
hp = zeros(nZones,1);
% LOOP
for ii = 1:nZones
    [hl(ii), hp(ii)] = boundedline(X(:, ii), Y(:, ii), XError(:, ii),...
        ['-', clr{ii}], 'transparency', 0.15, 'orientation', 'horiz');
end

The simplest method as shown by chadsgilbert:

% Create legend entries as a nZones x 8 char array of the format 'Zone #01',...
TagAx  = reshape(sprintf('Zone #%02d',1:nZones),8,nZones)'
legend(hp,TagAx)

... or for general more complex manipulations, set the legend display properties of the graphic objects:

% Do not display lines in the legend
hAnn   = cell2mat(get(hl,'Annotation'));
hLegEn = cell2mat(get(hAnn,'LegendInformation'));
set(hLegEn,'IconDisplayStyle','off')

% Add legend
legend(TagAx);

There is not an easy way to do this, You have to go into the legend and shift things up:

The following makes a sample plot where the mean lines are not superimposed on the bound patches.

N = 10;
x = 1:N;
y = sin(x);
b = ones([N,2,1]);

[hl, hp] = boundedline(x, y, b);
lh = legend('hi','');

We get a structure g associated with the legend handle lh. If you look at the types of the children, you'll see that g2 is the mean line and g4 is the patch. So I got the vertices of the patch and used it to shift the mean line up.

g = get(lh);
g2 = get(g.Children(2));
g4 = get(g.Children(4));

v = g4.Vertices;
vx = unique(v(:,1));
vy = diff(unique(v(:,2)))/2;
vy = [vy vy] + min(v(:,2));

set(g.Children(2), 'XData', vx);
set(g.Children(2), 'YData', vy);

Not a simple answer, and definitely requires you do a crazy amount of formatting for a plot with more than one mean line/patch pair, especially since it will leave gaps in your legend where the last zone's mean line was.

As per your comment, if you just want the shaded error bars to mark the legend then it's pretty easy:

x = 0:0.1:10;
N = length(x);
y1 = sin(x);
y2 = cos(x);
y3 = cos(2*x);

b1 = ones([N,2,1]);
b2 = 0.5*ones([N,2,1]);
b3 = 0.1*ones([N,2,1]);

hold on
[hl, hp] = boundedline(x, y1, b1, 'r',  x, y2, b2, 'b', x, y3, b3,'c')

lh = legend('one','two','three');

That's a nice FEX entry. You can associate a specific set of handles with a legend. And luckily, boundedline already returns the handles to the lines separately from the handles to the patches.

>> [hl,hp] = boundedline([1 2 3],[4 5 6], [1 2 1],'b',[1 2 3],-[4 5 6],[2 1 1],'r');
>> %legend(hl,{'blue line' 'red line'}); % If you want narrow lines in the legend
>> legend(hp,{'blue patch' 'red patch'});  % If you want patches in the legend.
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!