随着 for 的进行,有没有办法更新图例?

Is there a way to update the legend as the for goes on?

我一直在考虑如何在 Matlab 中随着 for 的进行更新我的图例,基本上,我有一个 for 创建一个图表,该图表被添加到 plot (使用 hold on)在每次迭代中,我想更新上述情节的图例。 我是这样做的:

clear all; close all; clc;

x0 = 10;
t = linspace(0, 2, 100);
v0 = 0;
g = [10:10:100];
str = [];

hold on
for i = 1:length(g)
    x = x0 + v0*t - 1/2*g(i)*t.^2;
    v = v0 - g(i)*t;
    plot(t, x)
    axis([0, 2, -200, 10]);
    str = [str, sprintf("g = %d", g(i))];
    legend(str, 'Location','southwest');
    pause(0.3);
end
hold off

即使用那个改变大小的字符串 str。我觉得有一种更好、更高效的方法可以做到这一点,但我不知道如何解决这个问题。

一个改进是更新图例的String属性,而不是创建一个每次迭代中的新图例。这种“更新而不是 re-create”的想法是随时间变化的图形对象的常见做法,可以加快执行速度。在您的示例代码中,这几乎不会产生任何影响,但它看起来仍然是一种更简洁的方法:

clear all; close all; clc;

x0 = 10;
t = linspace(0, 2, 100);
v0 = 0;
g = [10:10:100];
str = [];

le = legend(str, 'Location','southwest'); %%% new: create empty legend
hold on
for i = 1:length(g)
    x = x0 + v0*t - 1/2*g(i)*t.^2;
    v = v0 - g(i)*t;
    plot(t, x)
    axis([0, 2, -200, 10]);
    str = [str, sprintf("g = %d", g(i))];
    le.String = str; %%% changed: update String property of the legend
    pause(0.3);
end
hold off

或者,您可以避免存储 str,直接将新部分追加到图例中。同样,这样做的主要原因是代码可以说看起来更清晰,因为您避免在两个地方(变量和图形对象)保留相同的信息:

clear all; close all; clc;

x0 = 10;
t = linspace(0, 2, 100);
v0 = 0;
g = [10:10:100];
% str = []; %%% removed

le = legend(str, 'Location','southwest'); %%% new: create empty legend
hold on
for i = 1:length(g)
    x = x0 + v0*t - 1/2*g(i)*t.^2;
    v = v0 - g(i)*t;
    plot(t, x)
    axis([0, 2, -200, 10]);
    % str = [str, sprintf("g = %d", g(i))]; %%% removed
    le.String = [le.String  sprintf("g = %d", g(i))]; %%% changed: append new string
    pause(0.5);
end
hold off

附带说明一下,说到性能,您可能希望将 clear all 替换为 clear;查看相关链接:1, 2, 3.

plot函数中使用DisplayName,在legend中切换AutoUpdate。这是我对你的 for-loop:

的尝试
for i = 1:length(g)
    x = x0 + v0*t - 1/2*g(i)*t.^2;
    v = v0 - g(i)*t;
    plot(t, x,'DisplayName',sprintf("g = %d", g(i)));
    axis([0, 2, -200, 10]);
%     str = [str, sprintf("g = %d", g(i))];
%     legend(str, 'Location','southwest');
    legend('Location','southwest','AutoUpdate',1);
    pause(0.3);
end