如何将文本标签(键)放在图例中线条的左侧?

How to put the text labels (keys) to the left of the lines in the legend?

我在很多地方搜索过,但没有找到一种方法来实现我想使用 MATLAB 实现的目标,即:将键(文本标签)放在 MATLAB 中图例中颜色线的左侧.

我想实现这个结果,这是使用 gnuplot 的默认结果(参见上面的 link),这显然可以使用 MATLAB 的表亲 Octave(参见 Octave's legend),它具有legend("left") "place[s] label text to the left of the keys."

的选项

是否可以使用 MATLAB 来实现?

使用 @nirvana-msu 提到的 legend 的第二个输出进行了轻微更新。

我们可以通过检索它们的当前位置并更改它来调整图例中文本和绘图对象的位置。图例中所有项的位置单位均为0~1之间的归一化数据单位

像下面这样的东西应该可以工作。

%// Create some random data and display
figure;
p = plot(rand(2,3));
[L, handles] = legend({'one', 'two', 'three'});

%// Get the text handles
texts = findall(handles, 'type', 'text');

%// Get the line handles
lines = findall(handles, 'type', 'line');

%// Get the XData of all the lines
poslines = get(lines, 'XData');

%// Subtract 1 from all the positions and take the absolute value
%// this will shift them to the other side as the xlims are [0 1]
set(lines, {'XData'}, cellfun(@(x)abs(x - 1), poslines, 'uni', 0))

%// Get the position of all of the text labels
postext = get(texts, 'Position');

%// Figure out where the lines ended up
xd = get(lines, 'xdata');
xd = cat(2, xd{:});

%// Have the labels be next to the line (with 0.05 padding)
positions = cellfun(@(x)[min(xd) - 0.05, x(2:3)], postext, 'uni', 0);
set(texts, {'Position'}, positions, ...
           'HorizontalAlignment', 'right');

R2014a

R2015b

这是一个适用于 HG1 和 HG2 的解决方案。

这个想法与@Suever 的回答有点相似——我们想翻转图例中的所有文本、线条和标记,但是有一些显着的区别:

  1. 无需使用 findall 搜索 linetext 句柄 - 它们可用作 legend 函数的第二个输出。
  2. 合理的位置应该是什么就不用去猜了。我们只需要对称地翻转所有控件。使用线条很容易,因为您有 XData 起点和终点。对于文本,它有点棘手,因为您需要控制 Position,即左边缘,但您需要知道文本宽度来计算对称变换。 Extent 属性 给了我们所缺少的东西。

代码:

hFig = figure();
axh = axes('Parent', hFig);
plot(axh, randn(100,2), '-*');
[~, hObjs] = legend(axh, {'first','second-some-long-text'});

for i = 1:length(hObjs)
    hdl = hObjs(i);
    if strcmp(get(hdl, 'Type'), 'text')
        pos = get(hdl, 'Position');
        extent = get(hdl, 'Extent');    % we need text x-position and width
        pos(1) = 1-extent(1)-extent(3); % symmetrical relative to center
        set(hdl, 'Position', pos);
    else     % 'line'
        xData = get(hdl, 'XData');
        if length(xData) == 2 % line
            xDataNew = [1-xData(2), 1-xData(1)];
        else % length(xData)==1, i.e. marker
            xDataNew = 1-xData;
        end
        set(hdl, 'XData', xDataNew);
    end
end

我决定对 HG2 案例采取稍微不同的方法。虽然承认有点傻,但如果最终导出图形,它实际上可能会有用。

我们所做的几乎是将所有可以想到的东西旋转 180°:

function q37286345
%// Define some functions:
f = {'sin(x)','cos(x)','-2E-3.*x.^3'};
figure(); hold on;
for ind1 = 1:numel(f)
  ezplot(f{ind1}, [-10 10]); 
end
title(''); %// Just because I find the default annoying :)
%// Rotate stuff:
[L,H] = legend(f{:},'Location','SouthWest');
[H(1:3).Rotation] = deal(180);
[H(1:3).HorizontalAlignment] = deal('right');
set(gca,'XTickLabelRotation',180,'YTickLabelRotation',180,...
        'XAxisLocation','top','YAxisLocation','right');

结果大致如下:

有几个容易补救的副作用:

  • 图例输入顺序将与绘图顺序相反(除非 LegendChildren 被重新排序。
  • 轴的标签也需要旋转(或消除...)。

旁注:

我们可以探索 Legend 元类 ('matlab.graphics.illustration.Legend') 以了解有关 HG2 的更多信息:

%% // Exploring.....
mc = metaclass(L);
pl = {mc.PropertyList.Name}.'; %'
ml = {mc.MethodList.Name}.'; %'
s = struct(L);