Plotting graph using for loop in MATLAB

16,635

Solution 1

Why this happens...

With plot(x(i),y) you are plotting 100 single points (one in each iteration) and they are not shown by default. Therefore the plot looks empty.


Solution 1: Vectorized calculation and direct plot

I assume you meant to draw a continuous line. In that case no for-loop is needed because you can calculate and plot vectors directly in MATLAB. So the following code does probably what you want:

x = linspace(0,2*pi,100);
y = sin(x);
plot(x,y);

Note that y is a vector as well as x and that y(n) equals to sin(x(n)) for all n. If you want to plot the points itself, use LineSpec-syntax when calling plot like this1:

plot(x,y,'*');

1) Other types of points are possible as well, see the above linked documentation.


Solution 2: Calculate values within for-loop and plot afterwards

If you want to calculate the values within a for-loop and plot it afterwards: Pre-allocate the needed variable (in this case y), calculate the values within the for-loop and finally plot it with one single command after the calculation.

x = linspace(0,2*pi,100);

y = zeros(size(x));
for i = 1:numel(x)
    y(i) = sin(x(i));
end

plot(x,y);

Solution 3: Dynamically update plot while calculating

In case you insist on plotting within each iteration, the previous code from Solution 2 can be expanded as follows: Create a figure, add an 'empty' plot to it and store its handle. Within the for-loop calculate the values and add them to the y-vector as shown above. As a last step you can update the plot by changing its XData and YData properties and calling drawnow. Note that calling plot every time within the for-loop is unnecessarily expensive and I don't recommend it.

% create figure and plot
figure;
ph = plot(0,0);
ax = gca;
set(ax,'XLim',[0,2*pi]);
set(ax,'YLim',[-1,1]);

% calculate and update plot
x = linspace(0,2*pi,100);
y = zeros(size(x));
for i = 1:numel(x)
    y(i) = sin(x(i));
    set(ph,'XData',x(1:i));
    set(ph,'YData',y(1:i));
    drawnow;
end

Solution 2

Simple approach

If you want to draw a curve as you add data, try the following:

x = linspace(0,2 * pi, 100);
y = zeros(size(x));
for i=1:numel(x)
     y(i) = sin(x(i));
     plot(x(1:i), y(1:i), 'color', 'r')
     drawnow();
end

Be aware that the plot automatically tries to set x and y limits (curve is scaled to the plot window), to prevent that you have to manually set the x- and y-limits with xlimand ylim.

As Matt wrote in his answer, calling plot in each iteration is quite expensive (i.e. time consuming). Therefore I suggest using datasources:

Update graph using data sources

% Create a panel and axes object
h_panel = uipanel;
h_axes = axes( 'Parent', h_panel);

% Create data sources
x = linspace(0,2 * pi, 100);
y = zeros(size(x));

% Create graph object, in this case stairs 
% and bind the variables x and y as its data sources
h_stairs = stairs(h_axes, x, y, 'XDataSource', 'x', 'YDataSource', 'y');

for i=1:size(x)
    y(i) = sin(x(i));
    % Update the data of the stairs graph
    refreshdata(h_stairs); 
    drawnow();
end

The call to drawnow isn't neccessary in each iteration, it is only used to update the visuals, so you can see the changes directly.

Share:
16,635
cathy305
Author by

cathy305

Updated on June 04, 2022

Comments

  • cathy305
    cathy305 almost 2 years

    I'm trying to plot a simple graph using for loop as shown below

    x=linspace(0,2*pi,100);
    for i=1:numel(x)
        y=sin(x(i));
        plot(x(i),y)
        hold on
    end
    

    However, nothing appear on my figure. Why is that?

  • cathy305
    cathy305 almost 8 years
    Thank you for the answer, but my intention is to use for loop to plot a graph. So does that mean I cannot draw continuous line using for loop?
  • Matt
    Matt almost 8 years
    What do you want to achieve in the end? Creating a plot of values calculated within a for-loop? Or does it really need to draw in each iteration? If yes, why?
  • cathy305
    cathy305 almost 8 years
    Yes, I want to plot values, error values to be exact, calculated within a for-loop in each iteration to show that the error is actually decreasing as epoch increases, which means accuracy is getting higher.
  • Matt
    Matt almost 8 years
    @cathy305 I updated my answer so it should cover all the possibilities.