图例位置 'Best',但尽可能位于角落

Legend Location 'Best', but still in corner if possible

我想将图例的位置设置为 'Best'(例如 legend('y1','y2','Location','Best')),这样图例就不会与我的线条发生冲突,但与此同时,我更希望拥有如果可能的话,它会在一个角落里,而不会发生数据冲突。有没有办法实现这个?

我没有完整的答案,只有一个草图。但是,您可以尝试先将图例设置在角落

a=legend('y1', 'y2', 'Location', 'NorthEast')

然后获取它的位置

get(a,'Position')

您可以将此位置转换为坐标并简单地测试您的线条是否跨越图例的任何边界使用 http://www.mathworks.com/matlabcentral/fileexchange/11837-fast-and-robust-curve-intersections .如果是这种情况,请尝试另一个角,直到没有角为止。在这种情况下,使用 'Best'.

万一有人对此感兴趣,我写了一个基于@S.. answer 的函数,我想要实现的。这是代码:

function setPositionCornerBest( figureHandle )
%Sets the Location of the legend of the figure that is referenced by figureHandle to one of the Corners if there is no data in the Corners. Otherwise it sets it to 'Best'
h = figureHandle;

figObjects = get(h,'Children');
legHandle = findobj(figObjects,'Tag','legend');
axHandle = findobj(figObjects,'Type','axes','-and','Tag','');
lineHandle = findobj(figObjects,'Type','line','-and','Parent',axHandle);
axPos = get(axHandle,'Position');

LimX = get(axHandle,'XLim');
LimY = get(axHandle,'YLim');

xScaling = (LimX(2)-LimX(1))/axPos(3);
yScaling = (LimY(2)-LimY(1))/axPos(4);

locCell = {'NorthWest','NorthEast','SouthEast','SouthWest'};
ii = 1;
interSecFlag = true;

while (interSecFlag) && (ii<=4)
    set(legHandle,'Location',locCell{ii});
    legPos = get(legHandle,'Position');

    x(1) = LimX(1)+(legPos(1)-axPos(1))*xScaling;
    x(2) = x(1);
    x(3) = LimX(1)+(legPos(1)+legPos(3)-axPos(1))*xScaling;
    x(4) = x(3);
    x(5) = x(1);

    y(1) = LimY(1)+(legPos(2)-axPos(2))*yScaling;
    y(2) = LimY(1)+(legPos(2)+legPos(4)-axPos(2))*yScaling;
    y(3) = y(2);
    y(4) = y(1);
    y(5) = y(1);

    for jj = 1:numel(lineHandle)
        xline = get(lineHandle(jj),'XData');
        yline = get(lineHandle(jj),'YData');
        [xInter ~] = intersections(x,y,xline,yline);
        if numel(xInter) == 0
            xInterFlag(jj) = 0;
        else
            xInterFlag(jj) = 1;
        end
    end

    if all(xInterFlag==0)
        interSecFlag = false;
    end

    ii = ii + 1;
end

if interSecFlag
    set(legHandle,'Location','Best');
end

end