在Matlab中为图例设置标题 [英] Setting a title for a legend in Matlab

查看:970
本文介绍了在Matlab中为图例设置标题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码是我能找到的最多最小,完整和可验证的示例.我的真实情况要复杂得多:

The following code is the most Minimal, Complete, and Verifiable example that I could find. My true case is much more complicated:

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

结果是:

您可以清楚地看到,上图例标题出了点问题.不知何故,要求图例的att输出会干扰其标题.首先,由于某种原因,它使它不可见,但是上面的代码已经解决了这个问题.

As you can clearly see, something is wrong with the upper legend title. Somehow, asking for the att output of the legend interfere with its' title. First, for some reason, it makes it invisible, but that is already solved in the code above.

主要问题是它的位置-它似乎没有这样的属性,因此一旦设置,我将无法移动它.

The main problem is with its position - it doesn't seem to have such a property, so once set I can't move it.

我在未记录的Matlab 中阅读了这篇文章,并且我可以自己想到一些类似的技巧(例如使用text和图例的位置),但是我的情况非常复杂,我已经配置了很多图例,并且每个图中都有多个坐标轴.因此,我更喜欢一个简单且可行的解决方案,该解决方案依赖图例标题的原始功能.

I read this post in Undocumented Matlab and I can think of some similar hacks by myself (like using text with the position of the legend), but my situation is very complicated, and I already configure the legend a lot and have several axes in every figure. Thus, I prefer a simple and working solution that rely on the original functionality of the legend title.

我使用Matlab 2016a.

I use Matlab 2016a.

推荐答案

注意!此答案使用了未公开的功能,该结果已在2016a和2017a版本上进行了测试,在其他版本中可能会有所不同. 在评论中让我知道这是否也适用于其他版本的Matlab.

Caution! This answer uses undocumented features, the result was tested on versions 2016a and 2017a, and may differ in other versions.
Let me know in the comments if this also works for other versions of Matlab.

经过对未记录的属性的传说.对问题中最直接的答案是将图例标题的位置重新设置为其位置.可以通过图例标题的 hidden 属性NodeChildren的属性Position来完成.

I found the answer after some research of the undocumented properties of the legend. The most direct answer to the problem in the question is to set the position of the legend title back to its place. This can be done with the property Position, that is part of the hidden property NodeChildren, of the legend title.

图例框实际上只是一个小轴对象,因此相对于轴框对位置单位进行了归一化.如果我们在创建图例后立即查看它,则会得到:

The legend box is effectively just a small axes object, so the position units are normalized relative to the axes box. If we look at it just after creation of the legend we get:

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

ans =
     0     0     0

在哪里可以看到问题中的图例.现在,我们可以使用以下方法将其移回正确的位置:

Which is where we see the legend in the question. Now we can move it back to its correct place with:

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

在这里,我将其放置在水平轴(x = 0.5)的中心,垂直轴(y = 1.5)的上方,深度轴不相关,因此它为零(z = 0):

Here I placed it at the center of the horizontal axis (x = 0.5), above the vertical axis (y = 1.5), and the depth axis is irrelevant so it's zero (z = 0):

如果图例将干扰数据(例如,图例位于数据轴之外),则不会引起您的困扰,那么您可以在此处停止.如果没有,请继续阅读...

If you are not bothered by the option that the legend will interfere with the data, (e.g. your legend is outside the data axes) then you can stop here. If not, continue to read...

我们可以将背景色设置为白色:

We could set the background color to white:

hleg.Title.NodeChildren.BackgroundColor = 'w';

但是它看起来不太好,因为背景仅用于文本框,并且与图例框不对齐.因此,我更喜欢扩大图例框以包括标题,并向下移动图例属性以留出一些空间.这会花费更多的精力(因为我们需要为所有元素计算正确的位置),但是可以通过以下方式完成:

But it doesn't look good because the background is only for the text box, and is not aligned with the legend box. So I prefer to enlarge the legend box to include the title and move the legend attributes down to make some space. It takes more effort (because we need to calculate the right position for all elements), but it can be done in the following way:

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

上面的代码也针对一个数据系列进行了通用化,尽管我猜在某些情况下这将无法给出正确的解决方案,并且需要进行一些微调.

The code above is also generalized for more the one data series, although I guess that there are cases where this will fail to give the right solution and will need some fine tunings.

这篇关于在Matlab中为图例设置标题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆