Matlab中设置图例标题

5
以下代码是我能找到的最简洁、完整且可验证的示例。我的实际情况要复杂得多:
x = 1:0.1:10;
y = sin(x);

subplot 211
plot(x,y)
[leg,att] = legend('show');
title(leg,'my title')
leg.Title.Visible = 'on';

subplot 212
plot(x,y)
leg = legend('show');
title(leg,'my title')

这会导致:

legend title

正如您可以清楚地看到的那样,上方图例标题出现了问题。不知何故,在请求图例的att输出时会干扰其标题。首先,由于某种原因,它使其不可见,但这已经在上面的代码中解决了。
主要问题在于其位置——它似乎没有这样的属性,因此一旦设置就无法移动。
我阅读了Undocumented Matlab中的这篇文章,并且我可以自己想出一些类似的技巧(例如使用具有图例位置的text),但是我的情况非常复杂,并且我已经对图例进行了大量配置,并且每个图中都有几个轴。因此,我更喜欢一个简单而有效的解决方案,该方案依赖于图例标题的原始功能。
我使用的是Matlab 2016a。

你有在 文档 中阅读到这段关于 [lgd,icons,plots,txt] = legend(___) 重载的注意事项吗?注意:该语法不建议使用,因为它创建的图例不支持所有的图形特性。相反,使用 lgd = legend(__) 语法返回图例对象并设置图例属性。 - codeaviator
@Cebri 但是我需要访问这些图标,以便按照我的需求调整图例。否则我该如何更改它们的属性呢? - EBH
根据你所写的,最好的方法是使用带有图例位置的文本。如果你需要多次执行此操作,可以创建一个函数。 - oro777
这也发生在R2016b中。 - Luis Mendo
1个回答

3

注意!此答案使用了未公开的功能,已在2016a和2017a版本上进行测试,并且可能与其他版本不同。
如果这对其他版本的Matlab也起作用,请在评论中让我知道。


经过对图例的未公开属性进行一些研究后,我找到了答案。问题的最直接答案是将图例标题的位置设置回原位。这可以通过图例标题的NodeChildren(隐藏属性)的Position属性来完成。

图例框实际上只是一个小型的坐标轴对象,因此其位置单位是相对于坐标轴框归一化的。如果我们在创建图例后立即查看它,我们会得到:

[hleg,att] = legend('show');
title(hleg,'my title')
hleg.Title.NodeChildren.Position

ans =
     0     0     0

这就是我们在问题中看到的传说所在之处。现在,我们可以使用以下方法将其移回正确的位置:

hleg.Title.NodeChildren.Position = [0.5 1.5 0];

我将其放置在水平轴(x = 0.5)的中心,垂直轴(y = 1.5)上方,深度轴不相关,因此为零(z = 0): correct place 如果您不介意图例会干扰数据(例如,您的图例在数据轴之外),则可以停止阅读。否则,请继续阅读...
我们可以将背景颜色设置为白色:
hleg.Title.NodeChildren.BackgroundColor = 'w';

但是由于背景只适用于文本框,与图例框不对齐,所以这个效果并不好看。因此我更喜欢扩大图例框以包含标题并将图例属性下移以腾出一些空间。虽然需要付出更多的努力(因为我们需要计算所有元素的正确位置),但可以按照以下方式完成:

x = 1:0.1:10;
plot(x,sin(x),x,cos(x))
[hleg,icons,plots] = legend('show');
title(hleg,'my title')
hleg.Title.Visible = 'on';
% the addition in height needed for the title:
title_hight = hleg.Position(4)/numel(plots);
hleg.Position([2 4]) = [hleg.Position(2)-title_hight hleg.Position(4)+title_hight];
% calculate new position for the elements in the legeng:
new_pos = fliplr(0.5/(numel(plots)+1):1/(numel(plots)+1):1);
hleg.Title.NodeChildren.Position = [0.5 new_pos(1) 0];
% set the text to the right position:
leg_txt = findobj(icons,'Type','Text');
txt_pos = cell2mat({leg_txt.Position}.');
txt_pos(:,2) = new_pos(2:end);
set(leg_txt,{'Position'},mat2cell(txt_pos,[1 1],3));
% set the icons to the right position:
leg_att = findobj(icons,'Type','Line');
set(leg_att,{'YData'},mat2cell(repmat(repelem(new_pos(2:end).',...
    numel(plots)),1,2),ones(numel(plots)*2,1),2))

以上代码也适用于多个数据系列,尽管我想在某些情况下这可能无法给出正确的解决方案,需要进行一些微调。

大盒子


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接