Dynamic Legend (Updates in every recursion)

后端 未结 3 559
半阙折子戏
半阙折子戏 2020-12-05 06:03

I got a for i=1:15. Inside I generate a variable d=1:0.01:10, which is the x\'x axis and based on this, I create a continuous function F(d) which

相关标签:
3条回答
  • 2020-12-05 06:23

    Semidocumented Solution

    Adding lines to a legend in a loop can be accomplished with "dynamic legends", as described on undocumentedmatlab.com.

    The idea is to replace the legend command with:

    legend('-DynamicLegend');
    

    Then update the plot command with a DisplayName parameter:

    plot(d,F,'Linewidth',1.0,'DisplayName',sprintf('pitch,yaw: %d,%d',pitch,yaw));

    Then plots that are added to the axes get added to the legend:

    enter image description here

    If semi-documented features are not your cup of tea, use the DisplayName trick and simply toggle the legend off/on. That is, instead of -DynamicLegend:

    legend('off'); legend('show');
    

    A different variation that does not use either DisplayName or -DynamicLegend is to delete and recreate the legend with an array of stored strings.

    Official Solution

    The official solution recommended by MathWorks it so grab the existing legends` line handles and manually update the legend with those handles. This is pretty painful by comparison to the dynamic legend solution above:

    % Get object handles
    [LEGH,OBJH,OUTH,OUTM] = legend;
    
    % Add object with new handle and new legend string to legend
    legend([OUTH;p1],OUTM{:},sprintf('pitch,yaw: %d,%d',pitch,yaw))
    
    0 讨论(0)
  • 2020-12-05 06:23

    As of MATLAB 2017a, legends update automatically when adding or removing graphics objects.

    Thus, nothing specific needs to be done now. One creates the legend, then in a loop one can add lines to the axes and they'll automatically appear in the legend.

    0 讨论(0)
  • 2020-12-05 06:39

    As an HG2 (default in R2014+) alternative to @chappjc's official MW solution, one can take advantage of legend being re-implemented as its own class rather than a kludge of other graphics objects. This has cleaned up things a bit so they are simpler to interact with.

    Though these new legend objects do not have an exposed property linking legend items to plotted objects, they do have such a property, 'PlotChildren', which is an array of object handles.

    For example:

    x = 1:10;
    y1 = x;
    y2 = x + 1;
    
    figure
    plot(x, y1, 'ro', x, y2, 'bs');
    lh = legend({'Circle', 'Square'}, 'Location', 'NorthWest');
    
    pc = lh.PlotChildren
    

    Returns:

    pc = 
    
      2x1 Line array:
    
      Line    (Circle)
      Line    (Square)
    

    To update our legend object without calling legend again, we can modify the 'PlotChildren' and 'String' properties of our existing legend object. As long as there is a 'String' entry for each object in 'PlotChildren', it will be rendered in the legend.

    For example:

    y3 = x + 2;
    hold on
    plot(x, y3, 'gp');
    
    % To make sure we target the right axes, pull the legend's PlotChildren 
    % and get the parent axes object
    parentaxes = lh.PlotChildren(1).Parent;
    
    % Get new plot object handles from parent axes
    newplothandles = flipud(parentaxes.Children); % Flip so order matches
    
    % Generate new legend string
    newlegendstr = [lh.String 'Pentagram'];
    
    % Update legend
    lh.PlotChildren = newplothandles;
    lh.String = newlegendstr;
    

    Which returns:


    This functionality can be wrapped into a generic helper function to support appending one or more legend entries. We've done so with legtools on GitHub

    0 讨论(0)
提交回复
热议问题