MATLAB:用一个循环绘制一个轴:实线&传说

时间:2013-09-23 06:01:54

标签: matlab loops plot

我有两个不同的问题,但它们是一起发布的,因为我认为解决方案是相关的。我正在测试牛顿和割线方法(每个方法都是用循环实现的),并在同一轴上绘制结果与计算时间的关系来比较它们。我希望(离散)牛顿方法结果用蓝线连接,割线方法用红线表示。反过来,这些线由相应的图例注释。这种情况不会发生,因为情节中的每个点似乎都被考虑在单个对象上,因为它们是单独创建的。并且legend命令会显示两个蓝色星号而不是蓝色星号和一个红色星号(我希望我可以在此处发布我的情节,但我还没有图像权限。)

这是我的缩写代码:

f = (x) % define function
figure
hold on

%% Newton
tic
while % terminating condition
    % [Newtons method]

    t = toc;
    plot(t,log(abs(f(z)),'b*-')
end

%% Secant
tic
while % terminating condition
    % [secant method]

    t = toc;
    plot(t,log(abs(f(z)),'r*-')
end

legend('Newton''s','Secant')

无论如何,'-'中的linespec都没有做任何事情,因为只绘制了一个点,而不是一条线。我知道我可以用plot([t_old t],[log(abs(f(z_old) log(abs(f(z)])之类的每次迭代制作一个线图,但这并不理想,尤其是因为log(abs(f(z_old)))每次都必须重新评估。此外,这不会解决传说中的问题。

我认为如果我能让MATLAB了解我正在尝试在轴上创建两个对象,一条蓝线和一条红线,这两个问题都将得到解决。谢谢。

3 个答案:

答案 0 :(得分:1)

如果您不想将x / y数据存储在矢量中,然后重新绘制整个矢量,您可以使用以下代码添加到绘图线:

hNewton = [];
while % terminating condition
    % [Newtons method]
    t = toc;    
    if isempty(hNewton)
        hNewton = plot(t,log(abs(f(z))),'b*-');  % First time through plot and save the line handle
    else
        % On all subsequent passes, just add to the lines X/Y data
        set(hNewton,'XData',[get(hNewton,'XData')  t]);
        set(hNewton,'YData',[get(hNewton,'YData')  log(abs(f(z)))]);
    end
end

由于现在只有2行,所以图例按预期工作。

或者,您可以将代码添加到函数

中的现有行
function hLineHandle = AddToLine( hLineHandle, xData, yData, lineStyle )
% AddToLine - Add data to a plotted line
    if isempty(hLineHandle)
        hLineHandle = plot(xData,yData, lineStyle);
    else
        set(hLineHandle,'XData',[get(hLineHandle,'XData')  xData]);
        set(hLineHandle,'YData',[get(hLineHandle,'YData')  yData]);
    end
end

这使得主脚本/函数中的代码更加清晰。

hNewton = [];
while % terminating condition
    % [Newtons method]
    t = toc;    
    hNewton = AddToLine(hNewton,t, log(abs(f(z))),'b*-' );
end

答案 1 :(得分:1)

您可以使用line对象,例如:

f = (x) % define function
figure
hold on
lHandle1 = line(nan, nan); %# Generate a blank line and return the line handle
lHandle2 = line(nan, nan); %# Generate a blank line and return the line handle

%% Newton
tic
while % terminating condition
    % [Newtons method]
    t = get(lHandle1, 'XData');
    Y1 = get(lHandle1, 'YData');

    t = toc;
    Y1 = [Y1 log(abs(f(z)];
    set(lHandle1, 'XData', t, 'YData', Y1, 'LineWidth', 2 ,'Color' , [0 1 0]);

end

%% Secant
tic
while % terminating condition
    % [secant method]
    t = get(lHandle2, 'XData');
    Y2 = get(lHandle2, 'YData');

    t = toc;
    Y2 = [Y2 log(abs(f(z)];
    set(lHandle2, 'XData', t, 'YData', Y2, 'LineWidth', 2 ,'Color' , [1 0 0]);

end

legend('Newton''s','Secant')

答案 2 :(得分:1)

仅显示代码的相关部分以提出问题的良好示例。其他人已经解释了让传奇按照你的意愿行事的技巧。我会采用不同的解决方案,将测量值保存在矢量中并在循环后执行绘图。这有两个优点:您不必使用图例来处理这些技巧,但更重要的是,您没有在循环中执行绘图,可能需要花费大量时间。我猜你的时间由绘图控制,所以算法的影响很难显示在结果中。因此,将代码更改为此类(未经测试):

f = (x) % define function
% preallocate plenty of space
[t_newton, t_secant, f_newton, f_secant] = deal(nan(1, 1000));

%% Newton
tic;
i = 1;
while % terminating condition
    % [Newtons method]
    f_newton(i) = current_result;
    t_newton(i) = toc;
    i = i + 1;
end

%% Secant
tic;
i = 1;
while % terminating condition
    % [secant method]
    f_secant(i) = current_result;    
    t_secant(i) = toc;
    i = i + 1;
end

% trim NaNs (not really needed, not plotted anyhow)
t_newton = t_newton(isfinite(t_newton));
f_newton = f_newton(isfinite(f_newton));
t_secant = t_secant(isfinite(t_secant));
f_secant = f_secant(isfinite(f_secant));

% do the plot
semilogy(t_newton, abs(f_newton), t_secant, abs(f_secant))
legend('Newton''s','Secant')