Matlab:结合阴影误差和实线平均值的传说

时间:2013-07-12 14:23:22

标签: matlab legend

我正在使用this FEX entry绘制在X轴上绘制的变量的水平阴影误差线。此变量绘制在不同的区域/区域中,因此,3个区域有3个阴影误差条。 我想将误差条的图例(阴影区域)以及任何区域的平均值(实线)组合成一个由实线表示的图例(或补丁内的实线) )与区域颜色相同。

我的代码工作方式用于绘图:我正在绘制方式的合成示例如下所示

fh = figure();
axesh = axes('Parent', fh);
nZones = 4;
nPts = 10;
X = nan*ones(nPts, nZones);
Y = nan*ones(nPts, nZones);
XError = nan*ones(10, 4);
clr = {'r', 'b', 'g', 'm', 'y', 'c'};
for iZone = 1:nZones
    X(:, iZone) = randi(10, nPts, 1);
    Y(:, iZone) = randi(10, nPts, 1);
    XError(:, iZone) = rand(nPts, 1);
    % Append Legend Entries/Tags
    if iZone == 1
        TagAx = {['Zone # ', num2str(iZone)]};
    else
        TagAx = [TagAx, {['Zone # ', num2str(iZone)]}];
    end
    hold(axesh, 'on')
    [hLine, hPatch] = boundedline(X(:, iZone), Y(:, iZone), XError(:, iZone),...
        strcat('-', clr{iZone}), axesh, 'transparency', 0.15,...
        'orientation', 'horiz');
    legend(TagAx);
    xlabel(axesh, 'X', 'Fontweight', 'Bold');
    ylabel(axesh, 'Y', 'Fontweight', 'Bold');
    title(axesh, 'Error bars in X', 'Fontweight', 'Bold');
end

当前正在显示的方式

enter image description here

我做过什么: 正如有人在该文件的FEX页面的comment section中建议在boundedline code的第314行之后添加以下代码。

set(get(get(hp(iln),'Annotation'),'LegendInformation'),'IconDisplayStyle','off');

然而,在这样做时我得到了这个错误:

  

名称“注释”不是实例的可访问属性   class'root'。

编辑:前两个答案建议访问补丁和行的图例句柄,它们由函数boundedline作为输出返回。我试过了,但问题仍未解决,因为图例条目仍然与区域不一致。

3 个答案:

答案 0 :(得分:4)

没有一种简单的方法可以做到这一点,你必须进入传奇并改变方向:

以下是一个样本图,其中平均线没有叠加在绑定的补丁上。

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

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

我们获得了与图例句柄g相关联的结构lh。如果您查看子项的类型,您会看到g2是平均线,g4是补丁。所以我得到了补丁的顶点并用它来移动平均线。

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);

enter image description here

不是一个简单的答案,并且肯定要求你为一个具有多个平均线/补丁对的情节做一些疯狂的格式化,特别是因为它会在你的图例中留下最后一个区域的平均线所在的间隙。

根据你的评论,如果你只想让阴影的误差条标记传说,那么它很容易:

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');

enter image description here

答案 1 :(得分:4)

control legends有直接的一般方法。您只需选择不显示行条目,方法是提取'Annotation'属性并将'IconDisplayStyle'设置为'off'

此外,为了使用chadsgilbert的解决方案,您需要从每次循环迭代中收集每个补丁句柄。我稍微重构了一下你的代码,这样它就可以用于两种解决方案。

% 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

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)

...或者对于一般更复杂的操作,设置图形对象的图例显示属性:

% 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);

答案 2 :(得分:1)

这是一个很好的FEX条目。您可以将特定的句柄集与图例相关联。幸运的是,boundedline已经将句柄返回到与补丁的句柄分开的行。

>> [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.