【问题标题】:Dynamic Legend (Updates in every recursion)动态图例(每次递归更新)
【发布时间】:2014-03-08 07:09:14
【问题描述】:

我收到了for i=1:15。在里面我生成了一个变量d=1:0.01:10,它是x'x 轴,基于此,我创建了一个连续函数F(d),它有2 个唯一变量pitch 和yaw。然后我使用cmap = hsv(15); 在每次递归中使用不同的颜色来绘制它。那么就是:

d=1:0.01:10;
cmap = hsv(15);

for i=1:15
    pitch = unidrnd(10);
    yaw   = unidrnd(10);

    for j=1:length(d)
        F(j) = d(j)*3*pitch*yaw; %// some long calculation here
    end

    p1 = plot(d,F,'Linewidth', 1.0);
    title ('blah blah')
    set(p1, 'Color', cmap(i,:));
    hold on;
    legend (['pitch,yaw:', num2str(pitch) num2str(yaw)]) 
end 
hold off;

此代码在每次递归中更新唯一的俯仰角、偏航角值(它们之间没有空格,因此有点烦人)但未能:

  1. 应用适当的颜色,在图中可见。
  2. 保留上一次迭代的颜色和pitch,yaw 的值。

【问题讨论】:

  • 不确定你想做什么,但每次迭代结束时drawnow 可能有用
  • 不幸的是,drawnow 没有任何改变。

标签: matlab legend matlab-figure figure


【解决方案1】:

半文档化解决方案

可以使用“动态图例”,as described on undocumentedmatlab.com,在循环中向图例添加线条。

想法是将legend命令替换为:

legend('-DynamicLegend');

然后使用DisplayName 参数更新plot 命令:

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

然后添加到轴的图被添加到图例中:

如果您不喜欢半记录的功能,请使用DisplayName 技巧并简单地将legend 切换为关闭/打开。也就是说,而不是-DynamicLegend

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

different variation that does not use either DisplayName or -DynamicLegend 是删除并使用存储的字符串数组重新创建图例。

官方解决方案

official solution recommended by MathWorks 抓住现有的图例线句柄并使用这些句柄手动更新图例。与上面的动态图例解决方案相比,这非常痛苦:

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

【讨论】:

  • .gif 的绝妙使用!
  • 这可以解决颜色问题,但我无法添加所需的值而不是单词 data%d。为.gif +1!
  • 有一个方法('DisplayName),更新了。
  • 太棒了。另请注意,您可以在plot 命令中指定颜色:p1=plot(d,F,'Linewidth', 1.0,'DisplayName', sprintf('pitch,yaw: %d,%d',pitch,yaw), 'Color', cmap(i,:));
  • Holy $*!(#*!。我不知道 MATLAB 有动态图例。还为 .gif 使用 +1。
【解决方案2】:

作为@chappjc 官方 MW 解决方案的 HG2(R2014+ 中的默认值)替代方案,可以利用将图例重新实现为自己的类而不是其他图形对象的集合。这已经清理了一些东西,因此它们更易于交互。

虽然这些新的legend 对象没有将图例项链接到绘图对象的exposed property,但它们确实有这样一个属性'PlotChildren',它是一个对象句柄数组。

例如:

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

返回:

pc = 

  2x1 Line array:

  Line    (Circle)
  Line    (Square)

要更新我们的legend 对象而不再次调用legend,我们可以修改现有legend 对象的'PlotChildren''String' 属性。只要'PlotChildren'中的每个对象都有一个'String'条目,就会在图例中呈现。

例如:

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;

返回:


这个功能可以被包装到一个通用的辅助函数中,以支持附加一个或多个图例条目。我们已经通过legtools on GitHub 做到了这一点

【讨论】:

    【解决方案3】:

    As of MATLAB 2017a,添加或删除图形对象时,图例会自动更新。

    因此,现在不需要做任何具体的事情。创建图例,然后在循环中向轴添加线,它们将自动出现在图例中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      相关资源
      最近更新 更多