【问题标题】:Legend Location 'Best', but still in corner if possible图例位置“最佳”,但尽可能在角落
【发布时间】:2016-04-08 05:10:52
【问题描述】:

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

【问题讨论】:

    标签: matlab matlab-figure legend legend-properties


    【解决方案1】:

    如果有人对此感兴趣,我编写了一个基于@S.. 的函数,它确实是我想要实现的。代码如下:

    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
    

    【讨论】:

    • 技巧问题:它也适用于对数图吗?
    • @AndrasDeak 如果答案是“不”,我看不出那个问题的诀窍:D
    • 好吧,这可能只是一个反问;)如:我没有尝试。
    • 你的脚本很棒。对我非常有用。但是,我应该报告一个小错误,当绘图限制不是默认值时(当它们与数据长度不一致时)需要更正表达式'x(1),x(3)',' y(1)', 'y(3)' 考虑到这一点。变为:x(1) = LimX(1)+(legPos(1)-axPos(1))*xScaling; x(3) = LimX(1)+(legPos(1)+legPos(3)-axPos(1))*xScaling; y(1) = LimY(1)+(legPos(2)-axPos(2))*yScaling; y(2) = LimY(1)+(legPos(2)+legPos(4)-axPos(2))*yScaling;
    • @JustinoRodrigues 感谢您的积极反馈。你是绝对正确的,谢谢你的提示。
    【解决方案2】:

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

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

    然后获取它的位置

    get(a,'Position')
    

    您可以将此位置转换为坐标并使用 http://www.mathworks.com/matlabcentral/fileexchange/11837-fast-and-robust-curve-intersections .如果是这种情况,请尝试另一个角落,直到没有角落。在这种情况下,请使用“最佳”。

    【讨论】:

    • 听起来不错。我会试试这个,让你知道它是否尽快工作。不过可能需要几天时间。到目前为止,感谢您的努力!
    • 等等,我如何将图例的位置转换为绘图坐标中的曲线?
    • 做起来有点烦,但是可以得到坐标轴(x和y轴)的位置,也知道它们的范围。因此,您可以使用它来转换坐标中的任何位置。我同意该解决方案非常丑陋,但它可能会起作用
    猜你喜欢
    • 1970-01-01
    • 2022-06-22
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多